恢复二叉搜索树
难度:hard 本次用时:20min
关键词:树,中序遍历
二叉搜索树中序遍历下有序,O(n)的话是遍历然后交换一个逆序对
从左到右是升序,第一个违反的数;从右往左降序,第一个违反的数(从交换来看就很容易理解)
时空复杂度都是O(n)
如何优化到常数空间?左端数可以通过记录pre来获取,第一次pre>cur,记住这个pre, 获取右端,从右往左看,也就是cur < pre的数,记住更新到最后的值
class Solution {
TreeNode* pre;
TreeNode* cur;
TreeNode* ext1;
TreeNode* ext2;
bool begins;
bool findext1;
void inOrder(TreeNode* root){
if (root == nullptr)
return;
inOrder(root->left);
if (begins){
pre = root;
begins = false;
}
cur = root;
if (pre->val > cur->val && findext1 == false){
ext1 = pre;
findext1 = true;
}
if (cur->val < pre->val)
ext2 = cur;
pre = cur; //记得更新pre
inOrder(root->right);
}
public:
void recoverTree(TreeNode* root) {
//init
begins = true;
findext1 = false;
pre = nullptr;
cur = nullptr;
ext1 = nullptr;
ext2 = nullptr;
//
inOrder(root);
//交换回去
if (ext1 == nullptr || ext2 == nullptr)
return;
int temp = ext1->val;
ext1->val = ext2->val;
ext2->val = temp;
}
};
优化一下代码,begins和findext1可以去除
class Solution {
TreeNode* pre;
TreeNode* cur;
TreeNode* ext1;
TreeNode* ext2;
bool findext1;
void inOrder(TreeNode* root){
if (root == nullptr)
return;
inOrder(root->left);
if (pre == nullptr){
pre = root;
}
cur = root;
if (pre->val > cur->val && ext1 == nullptr){
ext1 = pre;
}
if (cur->val < pre->val)
ext2 = cur;
pre = cur; //记得更新pre
inOrder(root->right);
}
public:
void recoverTree(TreeNode* root) {
//init
pre = nullptr;
cur = nullptr;
ext1 = nullptr;
ext2 = nullptr;
//
inOrder(root);
//交换回去
if (ext1 == nullptr || ext2 == nullptr)
return;
int temp = ext1->val;
ext1->val = ext2->val;
ext2->val = temp;
}
};
时间复杂度O(n).空间复杂度O(H) (递归栈深)