您的位置:首页 > 其它

[LeetCode] Recover Binary Search Tree

2014-08-06 10:39 441 查看
Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note: A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

分析:本题做的思路是找到两个需要交换的结点,把两个结点的val值进行交换即可。

以下两种方法都是LeetCode Discuss中的方法:

方法1:用递归或栈的方法对树进行中序遍历,当然这种方法不满足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 recover(TreeNode *root, TreeNode *&pre, TreeNode *&a, TreeNode *&b) {
if (root)
{
recover(root->left, pre, a, b);

if (root->val < pre->val)
{
if (!a) a = pre; //a should change once.
b = root; //b could change twice.
}
pre = root;

recover(root->right, pre, a, b);
}
}
void recoverTree(TreeNode *root) {
if (!root) return;

TreeNode p(numeric_limits<int>::min());
TreeNode *a, *b, *pre;
a = b = 0;
pre = &p;
recover(root, pre, a, b);
if (a && b)
{
swap(a->val, b->val);
}
return;
}
};


方法2:morris traversal的方法,这种方法借鉴线索二叉树的方法,即不用递归和栈,用改变树的关键结点的指向的方法来遍历二叉树,使用完指向信息后,再将树恢复。参见http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/

class Solution {
public:
void recoverTree(TreeNode *root) {
if (root == NULL) return;
TreeNode * ptr, *pred, * current;
TreeNode * pred1, * cur1, * pred2, * cur2;

current = root; ptr = pred = NULL;
pred1 = cur1 = pred2 = cur2 = NULL;

while (current != NULL){
if (current->left == NULL){
pred = current;
current = current->right;
}else{
ptr = current->left;
while (ptr->right != NULL && ptr->right != current)
ptr = ptr->right;
if (ptr->right == NULL){//构造线索二叉树
ptr->right = current;
current = current->left;
}else{                  //把线索二叉树恢复成原先的二叉树
ptr->right = NULL;
pred = current;
current = current->right;
}
}//end if
if (pred != NULL && current != NULL && pred->val > current->val){//找到待交换的2个数
if (pred1 == NULL) {
pred1 = pred;
cur1 = current;
}
else {
pred2 = pred;
cur2 = current;
}
}//end if
}//end if

int tmp;
if (pred1 != NULL && cur2 != NULL){//pred1和cur2交换
tmp = pred1->val;
pred1->val = cur2->val;
cur2->val = tmp;
}
else{                            //pred1和cur1交换
tmp = pred1->val;
pred1->val = cur1->val;
cur1->val = tmp;
}
}
};


把原理弄清楚,自己实现一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: