Leetcode No.99 restore binary search tree

1, Title Description

Give you the root node of the binary search tree root, and the two nodes in the tree are incorrectly exchanged. Please restore this tree without changing its structure.

Example 1: Input: root = [1,3,null,null,2] Output: [3,1,null,null,2] Explanation: 3 cannot be a left child because 3 > 1. Swap 1 and 3 to make the binary search tree valid.

Example 2: Input: root = [3,1,4,null,null,2] Output: [2,1,4,null,null,3] Explanation: 2 cannot be in the right subtree of 3 because 2 < 3. Swap 2 and 3 to make the binary search tree valid.

Tips:

The number of nodes on the tree is in the range [2, 1000]

-2^31 <= Node.val <= 2^31 - 1

2, Problem solving ideas

We need to consider the impact on the original binary search tree after the two nodes are incorrectly exchanged. For the binary search tree, we know that if we traverse it in the middle order, the value sequence is incrementally ordered. If we mistakenly exchange two nodes, it is equivalent to exchanging two values in this value sequence, which destroys the incrementity of the value sequence.

Let's see what happens if we exchange two values in an increasing sequence. Suppose there is an increasing sequence a=[1,2,3,4,5,6,7]. If we exchange two non adjacent numbers, such as 2 and 6, and the original sequence becomes a=[1,6,3,4,5,2,7], it is obvious that there are two positions in the sequence that do not meet AI < AI + 1, which are reflected in 6 > 3 and 5 > 2 in this sequence. Therefore, as long as we find these two positions, we can find the two nodes incorrectly exchanged. If we exchange two adjacent numbers, such as 2 and 3, there is only one position in the exchanged sequence, which does not satisfy AI < AI + 1. Therefore, there are either two or one positions in the whole value sequence that do not meet the conditions.

So far, the problem-solving method is ready:

Find the position in the binary search tree where the sequence of values obtained by sequence traversal does not meet the conditions. If there are two, which we record as i and j (i < j and ai > ai + 1 & & AJ > aj+1), then the node corresponding to the wrong exchange is the node corresponding to ai and the node corresponding to aj+1, which we record as x and y respectively. If there is one, we record it as i, then the node corresponding to the wrong exchange is the node corresponding to ai and the node corresponding to ai+1, which we record as x and y respectively. Just swap x and y nodes. In the implementation part, this method opens up a new array nums to record the value sequence obtained by middle order traversal, then linearly traverses to find two positions i and j, and re traverses the original binary search tree to modify the value of the corresponding node to complete the repair. See the following code for the specific implementation.

3, Code

class Solution {
    public void recoverTree(TreeNode root) {
        List<Integer> nums = new ArrayList<Integer>();
        inorder(root, nums);
        int[] swapped = findTwoSwapped(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);
    }

    public int[] findTwoSwapped(List<Integer> nums) {
        int n = nums.size();
        int x = -1, y = -1;
        for (int i = 0; i < n - 1; ++i) {
            if (nums.get(i + 1) < nums.get(i)) {
                y = nums.get(i + 1);
                if (x == -1) {
                    x = nums.get(i);
                } else {
                    break;
                }
            }
        }
        return new int[]{x, y};
    }

    public void recover(TreeNode root, int count, int x, int y) {
        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);
        }
    }
}

4, Complexity analysis

Time complexity: O(N), where N is the number of nodes of the binary search tree. It takes O(N) time to traverse the middle order. Judge that the two switching nodes are O(1) in the best case and O(N) in the worst case, so the total time complexity is O(N). Space complexity: O(N). We need to use the num array to store the middle order traversal list of the tree.

Posted on Mon, 29 Nov 2021 09:42:11 -0500 by lukevrn