二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
示例 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
解析:将二叉搜索树进行中序遍历得到的必然是一串严格递增的数组。
如果其中两个节点发生了交换,情况有两种:
1、相邻的两个节点交换例如 [1,2,4,3,5]
2、不相邻 [5,2,3,4,1]
观察两种情况的数字变化趋势,第一种情况中,出现了一次前一个数字比后一个数字大的现象,而第二种情况出现了两次。
因此定义两个节点,记录出现前一个数字大于后一个数字使得前后节点。
将这两个节点的值交换即可恢复二叉搜索树
class Solution {
public:
void recoverTree(TreeNode* root) {
if(root==0)
return;
stack<TreeNode*> a;
TreeNode* cur=root;
TreeNode* pre=NULL;
TreeNode* i=nullptr;
TreeNode* j=nullptr;
while(cur||!a.empty())
{
if(cur)
{
a.push(cur);
cur=cur->left;
}
else
{
cur=a.top();
//出现前大于后
if(pre&&pre->val>cur->val)
{
//第一次
if(i==NULL)
{
i=pre;
j=cur;
}
//第二次
else
{
j=cur;
}
}
pre=cur;
a.pop();
cur=cur->right;
}
}
int tmp = i->val;
i->val=j->val;
j->val=tmp;
}
};
如果不能理解的话,有一个效率不高但容易理解的办法。
把中序遍历出来的数组排个序
然后按照顺序重新赋值一遍即可。。。