其他LeetCode题目欢迎访问:LeetCode结题报告索引

题目链接

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?

分析:首先我们最直观的的想法是中序遍历得到中序序列,平衡二叉树的中序序列是非递减有序的。那么问题就转化成了在非递减有序序列中交换了两个数的位置,找出这两个数并恢复有序序列,这个问题可以通过遍历一遍有序序列分下面2步完成:

  1. 首先找到第一个错误的数first,即第一个比它后缀要大的数
  2. 然后要找到第一个错误的数应该放置的位置(这就是第二个错误的数),即要找到第一个比first大的数的前驱,这个前驱就是第一个错误的数应该放的位置,也就是第二个错误的数。(注意一个特殊情况{0,1},first为1,没有找到比first大的数,这是second就是最后一个数0)

算法1:我们可以用递归中序遍历(或者使用栈的非递归中序遍历)来实现,但是这样空间复杂度都是O(n)。下面代码是递归中序遍历,可以通过oj

 1 /**
 2  * Definition for binary tree
 3  * struct TreeNode {
 4  * int val;
 5  * TreeNode *left;
 6  * TreeNode *right;
 7  * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     void recoverTree(TreeNode *root) {
13         // IMPORTANT: Please reset any member data you declared, as
14         // the same Solution instance will be reused for each test case.
15         TreeNode *pre = NULL, *first = NULL, *second = NULL;
16         inorder(root, pre, first, second);
17         if(first != NULL)
18         {
19             if(second == NULL)second = pre;//树{0,1}就可能出现这种情况
20             int tmp = first->val;
21             first->val = second->val;
22             second->val = tmp;
23         }
24     }
25     //pre是中序序列中当前节点的前驱,first、second分别是要找的两个乱序节点
26     void inorder(TreeNode *root, TreeNode* &pre, TreeNode* &first, TreeNode* &second)
27     {
28         if(root == NULL)return;
29         if(root->left)inorder(root->left, pre, first, second);
30         if(pre != NULL)
31         {
32             if(first == NULL && root->val < pre->val)
33                 first = pre;
34             else if(first && root->val > first->val)
35                 {second = pre; return;}//两个错误位置都找到就退出
36         }
37         pre = root;
38         if(root->right)inorder(root->right, pre, first, second);
39     }
40 };
View Code

相关文章: