恢复二叉搜索树
题目:
给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
示例:
思路:
嘶,递归递了加一起得两个点。
笔试的题是,交换了若干个相邻结点的,恢复成一颗二叉搜索树。估计就应该只能o(n)的空间复杂度了。
这个写了一个巧妙一些的方法。
因为这道题只存在,两个结点互相交换。最多造成两个顺序不一致的情况。即前驱结点的值大于当前结点的值。
这是一个中序遍历,因为中序遍历二叉搜索树可以得到一个递增序列。
当存在两个顺序不一致的时候,就都记录下来,交换下标0.3记录的结点的值。
当存在一个顺序不一致的时候,证明就两个相邻的交换了,换回来即可。
如图:
通过代码:
巧妙:
/**
* 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<TreeNode*> v;
TreeNode* prev = nullptr;
void swap(int& a,int& b)
{
int t = a;
a = b;
b = t;
}
void order(TreeNode* root)
{
if(root == nullptr)
{
return;
}
order(root->left);
if(prev != nullptr && prev->val >= root->val)
{
v.push_back(prev);
v.push_back(root);
}
prev = root;
order(root->right);
}
void recoverTree(TreeNode* root) {
order(root);
if(v.size() != 2)
{
// v.erase(v[0]);
swap(v[0]->val,v[3]->val);
}
else
swap(v[0]->val,v[1]->val);
}
};
o(n)空间复杂度的:
/**
* 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> v;
int i = 0;
TreeNode* prev = nullptr;
void swap(int& a,int& b)
{
int t = a;
a = b;
b = t;
}
void order(TreeNode* root)
{
if(root == nullptr)
{
return;
}
order(root->left);
v.push_back(root->val);
order(root->right);
}
void reorder(TreeNode* root,int& i)
{
if(root == nullptr)
{
return;
}
reorder(root->left,i);
if(root->val != v[i])
{
root->val = v[i];
}
i++;
reorder(root->right,i);
}
void recoverTree(TreeNode* root) {
order(root);
sort(v.begin(), v.end());
reorder(root,i);
}
};