您的位置:首页 > 其它

LeetCode简易题解--098、099

2017-10-11 11:46 295 查看

98. Validate Binary Search Tree

题意简述:判断一颗二叉树是否是二叉搜索树(BST)。

Binary tree [2,1,3], return true.

Binary tree [1,2,3], return false.

中序遍历二叉树,判断得到的数组是否是升序的即可。用递归的方法也很简单,这里就不多说了。这里介绍的是非递归的方法。

非递归算法需要用到一个栈来做辅助。分为几个步骤:

首先从根节点开始,一直往左节点前进,将每一个节点都压入栈。这个过程做完之后,二叉树的最左边的节点都压入了栈。

将栈顶节点取出,此节点就是目前所遍历到的节点中最左边的节点。这个节点就是中序遍历最先访问的节点。

访问该节点(进行目标操作)。

令当前访问了的节点的右子节点为新的根节点,该子树成为新的二叉树以继续以上操作。

说明:第4个步骤其实就是递归地进行以上操作,只不过会以循环的形式进行。在向左子树一直前进的过程中,遇到的节点都被压入了栈,根据栈FIFO的性质,能够保证中序遍历的正确性。以上操作结束的边界是当前的根节点为NULL或者栈为空。

代码如下:

stack<TreeNode*> s;
while (root != NULL || s.size() != 0) { // 步骤4的一部分以及操作结束的边界
while (root != NULL) { // 步骤1
s.push(root);
root = root->left;
}
root = s.top();
s.pop();
// 步骤3,目标操作
root = root->right; // 步骤4
}


因此对这道题来说,在步骤3中将目前节点的值储存起来,得到的就是中序遍历的数组。判断数组是否是升序排序的即可。

最终提交的代码为:

class Solution {
public:
bool isValidBST(TreeNode* root) {
if (root == NULL) return true;
stack<TreeNode*> s;
stack<int> vals;
while (root != NULL || s.size() != 0) {
while (root != NULL) {
s.push(root);
root = root->left;
}
root = s.top();

4000
s.pop();
vals.push(root->val);
root = root->right;
}
int t1 = vals.top();
vals.pop();
while (vals.size() > 0) {
int t2 = vals.top();
vals.pop();
if (t1 <= t2) return false;
t1 = t2;
}
return true;
}
};


99. Recover Binary Search Tree

题意简述:二叉搜索树中的两个节点被交换了,找出这两个节点并交换回来,恢复BST的正确性。

核心代码与上一题是一样的,不同的地方在于处理节点的方式。

执行过程中始终记录当前的节点
root
和这个节点的上一个节点
pre
。用
big
记录错误的较大的那个节点,
small
记录作物的较小的那个节点。由于BST中序遍历得到的数组是升序的,因此被交换的两个节点中,前面那个值肯定比后面那个的值大。此处的问题在于如何判断节点是否是错误节点。方法是:

在执行过程中,若是当前节点的值小于上一个节点的值,那么错误的节点就在这两个节点中;并且,第一次遇到时,
pre
是错误节点(较大的节点),第二次遇到时,
root
是错误节点(较小的节点)。


例如,对中序数组
[1, 4, 3, 2, 5]
root
指向
3
时,错误节点为
pre(4)
root
指向
2
时,错误节点为
root(2)


以上我们假设会两次遇到错误节点,但是,如果错误节点相邻,那么只会遇到一次错误节点(此时前后两个节点都是错误节点)。因此,第一次遇到错误节点时,我们默认认为前后两个都是错误节点,用
big
small
记录下来。如果第二次遇到节点,说明上一次只有一个错误节点,并且此错误节点肯定是
big
small
的值是错误的,所以将
small
改为此时的
root
即可。完成以上操作,还需要一个标志位
flag


找到这两个节点之后,将值交换即可。

最终代码如下:

class Solution {
public:
void recoverTree(TreeNode* root) {
if (root == NULL) return;
TreeNode* ori_root = root;
stack<TreeNode*> s;
TreeNode* pre = NULL;
TreeNode* big = NULL;
TreeNode* small = NULL;
bool flag = true;
while (root != NULL || s.size() != 0) {
while (root != NULL) {
s.push(root);
root = root->left;
}
root = s.top();
s.pop();
if (pre != NULL && pre->val > root->val) {
if (flag) {
big = pre;
small = root;
flag = false;
} else {
small = root;
}
}
pre = root;
root = root->right;
}
int t = big->val;
big->val = small->val;
small->val = t;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: