题目


思路
首先来理解一下题目:一棵二叉搜索树中有两个节点被错误的交换,要求是恢复这颗二叉搜索树,那我们的思路要从哪里出发呢
- 我们知道,中序遍历的结果是一个递增的关系,因为中序遍历一棵二叉搜索树的顺序为:左子树——根节点——右子树,所以大概思路就是我们中序遍历一棵二叉树,找到不是递增的地方
- 我们还需要注意的是:交换的节点有两种情况:
- 相邻节点之间的交换,比如中序遍历后[1,2,3,4,5]中的2,3节点交换,那么只产生一对降序对
- 不相邻的两个节点交换,比如[1,2,3,4,5]中的2,5交换,那么就会产生两对降序对
- 那么我们可以设置两个指针,在搜寻到第一个逆序对时,将这两个指针指向这两个节点
- 如果还存在第二对逆序对,那么我们只需要将一个指针指向当前节点
- 最后交换这两个节点的关键字值即可
相关代码如下:
class Solution {
public:
TreeNode* first = NULL;
TreeNode* second = NULL;
TreeNode* pre = NULL;
void recoverTree(TreeNode* root) {
inoder(root);//中序遍历二叉树
//交换两个节点的关键字值
int i = first->val;
first->val = second->val;
second->val = i;
}
//中序遍历,寻找交换的两个节点
void inoder(TreeNode* root) {
if (root == NULL)
return;
inoder(root->left);
如果遇到降序对,则将指针指向这两个节点
if (pre && root->val < pre->val) {
if (first == NULL) {//第一次碰到逆序对
first = pre;
second = root;
}
else//第二次碰到逆序对,对应不相邻的两个节点交换
second = root;
}
pre = root;
inoder(root->right);
}
};
总结
这道题还是运用二叉搜索树的性质和中序遍历的性质解题,相对来说,二叉搜索树一般情况下都会与中序遍历相结合
本文介绍了一种利用中序遍历恢复错误交换节点的二叉搜索树的方法。通过两次遍历检测并修正逆序对,适用于相邻或非相邻节点交换场景。
347

被折叠的 条评论
为什么被折叠?



