参考文章:http://www.cnblogs.com/TenosDoIt/p/3445682.html
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?
LeetCode 上的Hard题目都不是很好想…
首先我们可以考虑一个顺序数组中有两个数据被倒置了该怎么做?
(其实也可以通过将二叉搜索树的中序遍历放到一个vector< TreeNode*>数组之中,就可以转化为这个问题)
解决思路是
从前往后找第一个逆序元素的位置,从后向前找第一个逆序元素的位置,交换
而如果不借助数组只使用栈呢?
首先我们最直观的的想法是中序遍历得到中序序列,平衡二叉树的中序序列是非递减有序的。那么问题就转化成了在非递减有序序列中交换了两个数的位置,找出这两个数并恢复有序序列,这个问题可以通过遍历一遍有序序列分下面2步完成:
- 首先找到第一个错误的数first,即第一个比它后缀要大的数
- 然后要找到第一个错误的数应该放置的位置(这就是第二个错误的数),即要找到第一个比first大的数的前驱,这个前驱就是第一个错误的数应该放的位置,也就是第二个错误的数。(注意一个特殊情况{0,1},first为1,没有找到比first大的数,这是second就是最后一个数0)
还有一种Mirror的方法可以在空间复杂度O(1)的情况下完成对二叉树的遍历,暂时不研究
class Solution {
public:
void recoverTree(TreeNode* root) {
TreeNode* pre=NULL,*first=NULL,*second=NULL;
inorder(root,pre,first,second);
if(second==NULL) second=pre;
swap(first->val,second->val);
}
void inorder(TreeNode* root,TreeNode* &pre,TreeNode* &first,TreeNode* &second){
if(!root) return;
inorder(root->left,pre,first,second);
if(pre!=NULL){
if(!first && pre->val>root->val)
first=pre;
else if(first && root->val>first->val){
second=pre;return;
}
}
pre=root;
inorder(root->right,pre,first,second);
}
};