leetcode_109 Recover Binary Search Tree

161 篇文章 0 订阅

题目:

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Example 1:

Input: [1,3,null,null,2]

   1
  /
 3
  \
   2

Output: [3,1,null,null,2]

   3
  /
 1
  \
   2

Example 2:

Input: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

Output: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

Follow up:

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

题目解析:两个节点的值交换了,变成了非BST,找出两个节点,交换回来,变成BST

解法一:递归inorder

代码如下

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* first = NULL;
    TreeNode* second = NULL;
    TreeNode* pre = NULL;
    void findReverse(TreeNode* root)
    {
        if(root == NULL)
            return;
        findReverse(root->left);
        if(pre != NULL && root->val < pre->val)
        {
            if(first == NULL)
            {
                first = pre;
                second = root;
            }
            else
            {
                second = root;
            }
        }
        pre = root;
        findReverse(root->right);
    }
    void recoverTree(TreeNode* root) {
         findReverse(root);
         int tmp = first->val;
         first->val = second->val;
         second->val = tmp;
    }
};

 

解法二:利用栈(inorder)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void recoverTree(TreeNode* root) {
        if(root == NULL)
            return;
        stack<TreeNode*> stk;
        TreeNode* pre = NULL;
        TreeNode* first = NULL, *second = NULL;
        while(root != NULL || !stk.empty())
        {
            while(root)
            {
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            if(pre != NULL && root->val < pre->val)
            {
                if(first == NULL)
                {
                    first = pre;
                    second = root;
                }
                else{
                    second = root;
                }
            }
            pre = root;    
            
            root = root->right;
        }
        if(first && second){
            int tmp = first->val;
            first->val = second->val;
            second->val = tmp;
        }
    }
};

解法三:利用线索树(inorder)

首先线索树的中序遍历算法:

当前遍历的节点为 cur。

1、cur.left 为 null,保存 cur 的值,更新 cur = cur.right

2、cur.left 不为 null,找到 cur.left 这颗子树最右边的节点记做 last

2.1 last.right 为 null,那么将 last.right = cur,更新 cur = cur.left

2.2 last.right 不为 null,说明之前已经访问过,第二次来到这里,表明当前子树遍历完成,保存 cur 的值,更新 cur = cur.right

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> InorderTree(TreeNode* root) {
        vector<int> res;
        TreeNode* cur = root;
        while(cur != NULL)
        {
            if(cur->left == NULL)
            {
                //val
                res.push_back(cur->val;)
                cur = cur->right;
            }
            else
            {
                /* left-subtree rightest node */
                TreeNode* pre = cur->left;
                while(pre->right != NULL && pre->right != cur)
                {
                    pre = pre->right;
                }
                if(pre->right == NULL)
                {
                    pre->right = cur;
                    cur = cur->left;
                }
                else
                {
                    //val;
                    res.push_back(cur->val);
                    pre->right = NULL;
                    pre = cur;
                    cur = cur->right;
                }
            }
        }     
    }
};

本题解法三节点代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void recoverTree(TreeNode* root) {
        TreeNode* cur = root;
        TreeNode* pre_nw = NULL;
        TreeNode* first = NULL,*second = NULL;
        while(cur != NULL)
        {
            if(cur->left == NULL)
            {
                //val;
                if(pre_nw != NULL && cur->val < pre_nw->val)
                {
                    if(first == NULL)
                    {
                        first = pre_nw;
                        second = cur;
                    }
                    else
                    {
                        second = cur;
                    }
                }
                pre_nw = cur;
                cur = cur->right;
            }
            else
            {
                TreeNode* pre = cur->left;
                while(pre->right != NULL && pre->right != cur)
                {
                    pre = pre->right;
                    
                }
                if(pre->right == NULL)
                {
                    pre->right = cur;
                    cur = cur->left;
                }
                else
                {
                    //val
                    if(pre_nw != NULL && cur->val < pre_nw->val)
                    {
                        if(first == NULL)
                        {
                            first = pre_nw;
                            second = cur;
                        }
                        else
                        {
                            second = cur;
                        }
                    }
                    pre_nw = cur;
                    pre->right = NULL;
                    pre = cur;
                    cur = cur->right;
                }
            }
        }
        int tmp = first->val;
        first->val = second->val;
        second->val = tmp;
    }
};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值