一、题目描述
给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
示例 1:
输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。
示例 2:
输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。
提示:
树上节点的数目在范围 [2, 1000] 内
-231 <= Node.val <= 231 - 1
二、准备条件
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
三、代码演示
我们使用中序遍历方法来解此题,用递归
class Solution {
TreeNode firstNode = null;
TreeNode secondNode = null;
TreeNode preNode = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
in_order(root);
int tmp = firstNode.val;
firstNode.val = secondNode.val;
secondNode.val = tmp;
}
private void in_order(TreeNode root) {
if (root == null) return;
in_order(root.left);
if (firstNode == null && preNode.val > root.val) firstNode = preNode;
if (firstNode != null && preNode.val > root.val) secondNode = root;
preNode = root;
in_order(root.right);
}
}
说明:
1、MIN_VALUE:指的是在int类型里面的最小值
2、因为是恢复这棵树,其中有两个节点位置反了,从第二个例子来看,我们可以发现这样的规律:
第一个节点,是第一个按照中序遍历时候前一个节点大于后一个节点,我们选取前一个节点,这里指节点 4;
第二个节点,是在第一个节点找到之后,后面出现前一个节点大于后一个节点,我们选择后一个节点,这里指节点 1;
所以在代码中我们创造了firstNode和secondNode两个节点和方法中的两次if判断,来将这两个错位的数字归位
3、两次递归,使得两个数字归位