root 是一棵错误的二叉搜索树(有2个节点被错误交换)
发生在逆序对的头,尾这两个位置
第2个错误节点:最后一个逆序对中较小的那个节点 second
/**
* Definition for a binary tree node.
* 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 {
// 中序遍历:时间复杂度O(n)、空间复杂度O(1)
/**
* 上一次中序遍历过的节点
*/
private TreeNode prev;
/**
* 第一个错误节点
*/
private TreeNode first;
/**
* 第二个错误节点
*/
private TreeNode second;
private void find(TreeNode node) {
// 出现了逆序对
if (prev != null && prev.val > node.val) {
// 第2个错误节点:最后一个逆序对中较小的那个节点
second = node;
// 第1个错误节点:第一个逆序对中较大的那个节点
if (first != null) return;
first = prev;
}
prev = node;
}
/**
* @param root 是一棵错误的二叉搜索树(有2个节点被错误交换)
*/
public void recoverTree(TreeNode root) {
findWrongNodes(root);
// 交换2个错误节点的值
int tmp = first.val;
first.val = second.val;
second.val = tmp;
}
private void findWrongNodes(TreeNode root) {
if (root == null) return;
findWrongNodes(root.left);
find(root);
findWrongNodes(root.right);
}
}