您的位置:首页 > 其它

LeetCode -- Recover Binary Search Tree 详细解答

2013-09-06 15:16 435 查看
题目内容:一个二叉搜索树中的两个节点被错误交换了,找出这两个节点。

空间复杂度为o(n)的解法很简单:中序输出该二叉树,然后查找输出序列中两个失序的元素即可。题目还要求有空复为o(1)的解法,代码如下:

/**
* Definition for binary tree
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void findpos(TreeNode *root, TreeNode * &pre, TreeNode * &p, TreeNode * &q) {
if (!root) return;
findpos(root->left, pre, p, q);
if (pre && pre->val > root->val) {
if (!p) p = pre;
q = root;
}
pre = root;
findpos(root->right, pre, p, q);
}
void recoverTree(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
TreeNode *p, *q, *pre;
pre = p = q = NULL;
findpos(root, pre, p, q);
int tmp = p->val;
p->val = q->val;
q->val = tmp;
}
};


解法思路为:

概括的说,findpos函数使用中序递归遍历整个BST,在遍历所有节点的左子树时,pre是root的左子节点,当pre大于root时即找到错误节点(标记为p);遍历任意节点的右子树时,root为pre的右子节点(注意顺序),当pre大于root时即找到第二个错误节点(标记为q)。

具体而言:
从根节点开始查找,重复执行第14行直至找到第一个左叶子节点,并设置pre为该左叶子节点后返回至上一层递归;
之后执行第15行,此时pre是root的左节点:
1) 当pre大于root时,pre即为错误节点,标记为p。查找到第一个错误节点后,pre变为root的父节点,root是pre的右节点,当pre大于root时,root就是是错误节点,标记为q,算法结束。
2) 若pre小于root时,改变pre并执行第20行,进入下一层递归;此时pre变为root的父节点,root是pre的右节点,若pre大于root,则pre就是错误节点,标记pre为p,之后逻辑和 1) 中类似,标记出q,算法结束

参考:/article/6711067.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: