恢复二叉搜索树
描述
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2]
1
/
3
2
输出: [3,1,null,null,2]
3
/
1
2
思路和代码1
用一个节点数组list来保存所有的节点,用一个值数组vals来保存所有的值,然后中序遍历每一个节点,将节点指针入list数组中,将节点的值入vals数组中,最后排序vals数组,将vals的值依次赋给list数组中的节点。
时间复杂度是O(NlogN),原因就在于排序。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void recoverTree(TreeNode* root) {
vector<TreeNode*> list;
vector<int> vals;
inorder(root, list, vals);
sort(vals.begin(), vals.end());
for(int i=0; i<vals.size(); i++)
{
list[i]->val = vals[i];
}
}
void inorder(TreeNode* root, vector<TreeNode*>& list, vector<int>& vals)
{
if(root == NULL)
return ;
inorder(root->left, list, vals);
list.push_back(root);
vals.push_back(root->val);
inorder(root->right, list, vals);
}
};
思路和代码2
中序递归的方式,有两个节点交换了。
pre表示当前中序遍历的前一个结点,二叉搜索树的中序排列应该是递增的。遇到第一个pre->val > root->val就用first指向pre,second指向root,这是相邻结点交换的情况,若是不相邻的结点交换,后面继续遍历会更新second的值,所以遍历完,如果first和second都不为NULL,那么就交换两者的值。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* pre = NULL;
TreeNode* first = NULL;
TreeNode* second = NULL;
void recoverTree(TreeNode* root) {
inorder(root);
if(first && second)
swap(first->val, second->val);
}
void inorder(TreeNode* root)
{
if(!root)
return ;
inorder(root->left);
if(pre == NULL)
pre = root;
else
{
if(pre->val > root->val)
{
if(first == NULL)
first = pre;
second = root;
}
pre = root;
}
inorder(root->right);
}
};
思路和代码3
上面是中序遍历的递归,中序遍历的moris遍历才更牛逼一点。first和second和上面递归一样的概念,但是这时parent代表当前遍历的前一个结点,pre代表左子树的最右结点,也就是mostright。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void recoverTree(TreeNode* root) {
TreeNode *first = NULL, *second = NULL, *parent = NULL;
TreeNode *cur, *pre;
cur = root;
while (cur)
{
if (!cur->left)
{
if (parent && parent->val > cur->val)
{
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
}
else
{
pre = cur->left;
while (pre->right && pre->right != cur) pre = pre->right;
if (!pre->right)
{
pre->right = cur;
cur = cur->left;
}
else
{
pre->right = NULL;
if (parent->val > cur->val)
{
if (!first) first = parent;
second = cur;
}
parent = cur;
cur = cur->right;
}
}
}
if (first && second) swap(first->val, second->val);
}
};