LeetCode 99恢复二叉搜索树 详细解读

题目:

给定二叉搜索树的根节点 root ,树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。

思路:

  • 首先注意题意:两个节点错误的交换,意思不是存在两个地方乱序,而是有两个节点值互换了。
  • 二叉搜索树即根节点左子树比根节点小。根节点右子树比根节点大。二叉搜索树的中序遍历是从小到大的有序集合。二叉搜索树中不包含重复元素。
  • 通过这些概念,我们可以直接进行中序遍历,将元素放到List集合中,获得的就是从小到大的数据集合(不考虑节点调换)。

难点: 常规思路直接中序遍历,之后排序,再重组二叉树,但是改变了结构同时时间复杂度较高。所以我们需要直接定位哪两个元素进行了交换。这道题我也是卡在这里。通过看官方题解,看到了十分灵巧的方法。

代码:

class Solution {
    
    
    public void recoverTree(TreeNode root) {
    
    
        List<Integer> nums = new ArrayList<Integer>();
        inorder(root, nums);
        int[] swapped = findchange(nums);
        recover(root, 2, swapped[0], swapped[1]);
    }
	//中序遍历,将元素放入集合中
    public void inorder(TreeNode root, List<Integer> nums) {
    
    
        if (root == null) {
    
    
            return;
        }
        inorder(root.left, nums);
        nums.add(root.val);
        inorder(root.right, nums);
    }
	//找到两个交换节点的索引并获取他们的值
	//十分灵巧的确定位置的方法,看不懂可以用{3,2,4,1,5}来进行模拟
    public int[] findchange(List<Integer> nums) {
    
    
        int n = nums.size();
        int index1 = -1, index2 = -1;
        for (int i = 0; i < n - 1; i++) {
    
    
            if (nums.get(i + 1) < nums.get(i)) {
    
    
                index2 = i + 1;
                if (index1 == -1) {
    
    
                    index1 = i;
                } else {
    
    
                    break;
                }
            }
        }
        int x = nums.get(index1), y = nums.get(index2);
        return new int[]{
    
    x, y};
    }

    public void recover(TreeNode root, int count, int x, int y) {
    
    
    	//使用count来作为标记,标记交换两次为界限
        if (root != null) {
    
    
            if (root.val == x || root.val == y) {
    
    
                root.val = root.val == x ? y : x;
                if (--count == 0) {
    
    
                    return;
                }
            }
            recover(root.right, count, x, y);
            recover(root.left, count, x, y);
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_43744992/article/details/121565671