# Leetcode notes -- modification and construction of binary tree in binary tree chapter

Posted by crimaniak on Thu, 17 Feb 2022 05:15:27 +0100

# preface

Modification of binary tree: such as flipping, merging, etc.
Construction of binary tree: such as constructing binary tree according to pre order traversal and middle order traversal or post order traversal and middle order traversal.
The question brushing route comes from: Code Capriccio

# Inscription

## 226. Flip binary tree

Turn over the two nodes of the tree and return to the two root s of the tree.

Example 1:
Input: root = [4,2,7,1,3,6,9]
Output: [4,7,2,9,6,3,1]

Example 2:
Input: root = [2,1,3]
Output: [2,3,1]

Example 3:
Input: root = []
Output: []

Solution:
Traverse the binary tree and exchange the values of the left and right child nodes

```class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
invertTree(root.left);
invertTree(root.right);
// Pre order and subsequent traversal are OK. Here is post order traversal
swap(root);
return root;
}
// exchange
public void swap(TreeNode root) {
TreeNode node = root.left;
root.left = root.right;
root.right = node;
}
}
```

## 106. Construct binary tree from middle order and post order traversal sequences

Given two integer arrays inorder and postorder, inorder is the middle order traversal of the binary tree and postorder traversal of the same tree, please construct and return this binary tree.

Example 1:
Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
Output: [3,9,20,null,null,15,7]

Example 2:
Input: inorder = [-1], postorder = [-1]
Output: [- 1]

Solution:

1. The last node of post order traversal is the root node.
2. Traversing the array in middle order, the left side is all the nodes of the left subtree, and the right side is all the nodes of the right subtree. We know the number of nodes n of the left subtree
3. In the post order traversal array, the first n nodes from the left are the nodes of the left subtree, and the following nodes are the nodes of the right subtree except the last one is the root node

Use recursive writing:

1. In addition to the two traversal arrays, the parameter needs to pass in the interval of the left subtree node and the interval of the right subtree node in the two arrays. The interval is uniformly closed on the left and open on the right
2. After recursion of the left and right subtrees, the root node is returned. As the child node of upper recursion
3. The postorder traversal array postorder is used to determine the root node. The middle order traversal array inorder is divided by the root node to obtain the left and right subtree intervals and the number of left subtree nodes of inorder
4. According to the number of left subtree nodes, the node intervals of the left and right subtrees of the postorder traversal array postorder are obtained
5. The inorder of the middle order traversal array has no nodes (each method is divided) and returns null
6. There is only one node left in inorder, which will be returned
```class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return build(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
public TreeNode build(int[] inorder, int inLeft, int inRight,
int[] postorder, int postLeft, int postRight) {
// There are no nodes in the interval
if (inRight - inLeft == 0) {
return null;
}
// There is only one node left, and the subscript is inLeft (because the interval is left closed and right open)
if (inRight - inLeft == 1) {
return new TreeNode(inorder[inLeft]);
}

// The last element is traversed in sequence, which is the root node of the current interval subtree
int rootVal = postorder[postRight - 1];
TreeNode root = new TreeNode(rootVal);
// Split point subscript
int rootIndex = -1;
// Find the root node in the middle order traversal. The left is the left subtree node and the right is the right subtree node
for (int i = inLeft; i < inRight; i++) {
if (inorder[i] == rootVal) {
rootIndex = i;
break;
}
}
// Number of nodes in the left subtree: rootIndex - inLeft, then the following sequence traverses the sub array:
//[postLeft, postLeft + number of left subtree nodes) is the node of the left subtree,
//[postLeft + number of left subtree nodes, postright - 1 (the last node is the root node, minus 1)) is the right subtree interval
root.left = build(inorder, inLeft, rootIndex,
postorder, postLeft, postLeft + (rootIndex - inLeft));
root.right = build(inorder, rootIndex + 1, inRight,
postorder,postLeft + (rootIndex - inLeft) , postRight - 1);
// Returns the root node of the current interval subtree
return root;
}
}
```

## 105. Construct binary tree from preorder and inorder traversal sequences

Given two integer arrays preorder and inorder, where preorder is the preorder traversal of the binary tree and inorder is the inorder traversal of the same tree, please construct the binary tree and return its root node.

Example 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

Example 2:
Input: preorder = [-1], inorder = [-1]
Output: [- 1]
Solution:
The difference is that the root node is on the leftmost side of the preceding traversal array, so the recursive interval of the lower layer changes slightly

```class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return build(preorder, 0, preorder.length, inorder, 0, inorder.length);
}
public TreeNode build(int[] preorder, int preLeft, int preRight,
int[] inorder, int inLeft, int inRight) {
// There are no nodes
if (inRight - inLeft == 0) {
return null;
}
// There is only one node left
if (inRight - inLeft == 1) {
return new TreeNode(inorder[inLeft]);
}
int rootVal = preorder[preLeft];
// Root node of current interval subtree
TreeNode root = new TreeNode(rootVal);
// Split point
int rootIndex = -1;
for (int i = inLeft; i < inRight; i++) {
if (inorder[i] == rootVal) {
// The subscript of the root node is the partition point
rootIndex = i;
break;
}
}
// Number of nodes in the left subtree: rootIndex - inLeft, then the following sequence traverses the sub array:
//Node interval of left subtree: [preLeft+ 1 (the first is the root node, so + 1), preLeft+ 1 + number of nodes of left subtree)
//Right subtree node interval: [preLeft+ 1 + number of left subtree nodes, preRight)
root.left = build(preorder, preLeft + 1, preLeft + 1 + (rootIndex - inLeft),
inorder, inLeft, rootIndex);
root.right = build(preorder, preLeft + 1 + (rootIndex - inLeft), preRight,
inorder, rootIndex + 1, inRight);
return root;
}
}
```

## 654. Maximum binary tree

Give a non repeating integer array nums. The maximum binary tree can be constructed recursively from nums with the following algorithm:
Create a root node with the maximum value in nums.
Recursively construct the left subtree on the subarray prefix to the left of the maximum.
Recursively construct the right subtree on the subarray suffix to the right of the maximum.
Returns the largest binary tree constructed by nums.

Example 1:
Input: num = [3,2,1,6,0,5]
Output: [6,3,5,null,2,0,null,null,1]
Explanation: recursive calls are as follows:

• The maximum value in [3,2,1,6,0,5] is 6, the left part is [3,2,1], and the right part is [0,5].
• The left part is the maximum value of [1,3], and the right part is the maximum value of [1,3].
• Empty array, no child nodes.
• The maximum value in [2,1] is 2, the left part is [] and the right part is .
• Empty array, no child nodes.
• There is only one element, so the child node is a node with a value of 1.
• The maximum value in [0,5] is 5, the left part is , and the right part is [].
• There is only one element, so the child node is a node with a value of 0.
• Empty array, no child nodes.

Example 2:
Input: num = [3,2,1]
Output: [3,null,2,null,1]
Solution:
If the above two questions are met, then this question is very simple.
Find the maximum number in the array as the split point. The left is the left subtree and the right is the right subtree

```class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return build(nums, 0, nums.length);
}
public TreeNode build(int[] nums, int left, int right) {
if (right - left <= 0) {
return null;
}
if (right - left == 1) {
return new TreeNode(nums[left]);
}
int rootVal = Integer.MIN_VALUE;
int maxIndex = -1;
for (int i = left; i < right; i++) {
if (nums[i] > rootVal) {
rootVal = nums[i];
maxIndex = i;
}
}
TreeNode root = new TreeNode(rootVal);
root.left = build(nums, left, maxIndex);
root.right = build(nums, maxIndex + 1, right);
return root;
}
}
```

## 617. Merge binary tree

Here are two binary trees: root1 and root2.
Imagine that when you overlay one tree over the other, some nodes on the two trees will overlap (while others won't). You need to merge the two trees into a new binary tree. The merging rule is: if two nodes overlap, add the values of the two nodes as the new values of the merged nodes; Otherwise, the non null node will be directly used as the node of the new binary tree.
Returns the merged binary tree.
Note: the merge process must start at the root node of the two trees.

Example 1:
Input: root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
Output: [3,4,5,5,4,null,7]

Example 2:
Input: root1 = , root2 = [1,2]
Output: [2,2]
Solution:
The returned binary tree does not overlap with the merged tree nodes

```class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
return build(root1, root2);
}
public TreeNode build(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) {
return null;
}
TreeNode root = null;
if (root1 == null) {
// The first node is empty
root =  new TreeNode(root2.val);
// Root1 is empty, root1 Left will cause null pointer exception, and the left child node will continue to be null during recursion
root.left = build(root1, root2.left);
root.right = build(root1, root2.right);
} else if (root2 == null) {
// The second node is empty
root = new TreeNode(root1.val);
root.left = build(root1.left, root2);
root.right = build(root1.right, root2);
} else {
// The two tree nodes are not null, and val is added
root = new TreeNode(root1.val + root2.val);
root.left = build(root1.left, root2.left);
root.right = build(root1.right, root2.right);
}
return root;
}
}
```

In order to simplify the code, if a tree is empty, you can directly return to the root node of the subtree of another tree and connect the subtree to the merged tree

```class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
return build(root1, root2);
}
public TreeNode build(TreeNode root1, TreeNode root2) {
if (root1 == null) {
// Returns the root node of the subtree that is not empty
return root2;
}
if (root2 == null) {
return root1;
}
TreeNode root = new TreeNode(root1.val + root2.val);
root.left = build(root1.left, root2.left);
root.right = build(root1.right, root2.right);
return root;
}
}
```