LeetCode Brush Questions: Tree 2

Binary tree

other

Rebuilding a binary tree: preorder traversal
Insert picture description here
For any tree, the form of preorder traversal is always
[root node, [preorder traversal result of left subtree], [preorder traversal result of right subtree]]

That is, the root node is always the first node in the preorder traversal. The form of the middle-order traversal is always
[[the result of the middle-order traversal of the left subtree], the root node, [the result of the middle-order traversal of the right subtree]]

As long as we locate the root node in the in-order traversal, then we can know the number of nodes in the left subtree and the right subtree respectively. Since the lengths of the pre-order traversal and the middle-order traversal of the same subtree are obviously the same, we can correspond to the result of the pre-order traversal and locate all the left and right parentheses in the above form.

Consider using a hash table to help us locate the root node quickly. For each key-value pair in the hash map, the key represents an element (the value of the node), and the value represents its position in the mid-order traversal. Before the process of constructing a binary tree, we can scan the list traversed in order to construct this hash map. In the subsequent process of constructing the binary tree, we only need O(1)O(1) time to locate the root node.

https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-by-leetcode-s/

There are also three traversal methods. The preorder traversal is used here
because each time the root node is first confirmed, and then the left and right children are confirmed.

class Solution {
    
    
    private Map<Integer, Integer> indexMap;
 
    public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
    
    
        if (preorder_left > preorder_right) {
    
    
            return null;
        }
 
        // 前序遍历中的第一个节点就是根节点
        int preorder_root = preorder_left;
        // 在中序遍历中定位根节点
        int inorder_root = indexMap.get(preorder[preorder_root]);        
        // 先把根节点建立出来
        TreeNode root = new TreeNode(preorder[preorder_root]);
 
        // 得到左子树中的节点数目
        int size_left_subtree = inorder_root - inorder_left;
        // 递归地构造左子树,并连接到根节点
        // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
        // 通过root.left的方式直接连接即可
        root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
        // 递归地构造右子树,并连接到根节点
        // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
        root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
        return root;
    }
 
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        int n = preorder.length;
        // 构造哈希映射,帮助我们快速定位根节点
        indexMap = new HashMap<Integer, Integer>();
        for (int i = 0; i < n; i++) {
    
    
            indexMap.put(inorder[i], i);
        }
        return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
    }
}

In-order traversal problem
Insert picture description here

What is the impact on the original binary search tree after the two nodes are incorrectly swapped? For a binary search tree, we know that if we traverse it in order, the sequence of values ​​obtained is in increasing order, and if we swap two nodes by mistake, it is equivalent to swapping two values ​​in this sequence of values , Destroying the incrementality of the value sequence.

What will happen if you swap two values ​​in an increasing sequence? Suppose there is an increasing sequence a=[1,2,3,4,5,6,7] a=[1,2,3,4,5,6,7]. If we exchange two non-adjacent numbers, such as 2 and 6, the original sequence becomes a=[1,6,3,4,5,2,7], then obviously there are two positions in the sequence that do not satisfy ai <ai+1, so as long as we find these two positions, we can find the two nodes that were incorrectly swapped.
If we exchange two adjacent numbers, such as 2 and 3, there is only one position in the exchanged sequence that does not satisfy ai<ai+1. Therefore, there are either two or one position that does not satisfy the condition in the entire value sequence.

Idea:
Get all the elements in the middle order traversal.
Check the out-of-order position and the number.
DFS traverse the tree again and exchange the values ​​of the two elements.

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);
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_38370441/article/details/115181373