Leetcode:99.恢复二叉搜索树

二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]

   1
  /
 3
  \
   2

输出: [3,1,null,null,2]

   3
  /
 1
  \
   2

示例 2:

输入: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

输出: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

解题思路:

二叉搜索树:中序遍历中没有逆序对。如果知道什么是中序遍历,还有二叉搜索树,本题只能算是easy。

按照题意只交换了二叉树的两个结点,这也就意味着是排序数组中交换了两个元素的位置,这么一想就会变得容易很多。

1. 交换的两个元素中序遍历相邻。这时只会出现一个逆序对,交换两个逆序对结点的的val即可。

2. 两个元素在中序遍历数组中不相邻。会出现两个逆序对,我们只需记录第一个逆序对的第一个结点,以及第二个逆序对的第二个结点即可,最后交换两个结点的val即可。

只需要记录逆序对的位置即可,因此仅用了常数个空间。

                        

C++代码
#define hasLChild(x) (!(x->left==NULL))
#define hasRChild(x) (!(x->right==NULL))
class Solution {
 public:
     void recoverTree(TreeNode* root) {
         //中序遍历
         In_order_traversal(root);
         swap(first->val, second->val);
     }
     void In_order_traversal(TreeNode* root) {
         if (sgn == 2) return;
         if (hasLChild(root)) In_order_traversal(root->left);
         if (temp == NULL) temp = root;
         else {
             if (temp->val > root->val) {//出现了逆序对
                 if (sgn == 0) { first = temp; second = root; sgn = 1; }
                 else { second = root; sgn = 2; }
             }
             temp = root;
         }
         if (hasRChild(root)) In_order_traversal(root->right);
     }
 private:
     TreeNode* temp = NULL;
     TreeNode* first, *second;
     int sgn = 0;
 };

猜你喜欢

转载自blog.csdn.net/qq_23523409/article/details/83993570
今日推荐