二叉树的修改与构造
文章目录
- 二叉树的修改与构造
- 1. "226. 翻转二叉树"
- 2. “105. 从前序与中序遍历序列构造二叉树”
- 3. "[ 从中序与后序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)"
- 4. “[654. 最大二叉树](https://leetcode-cn.com/problems/maximum-binary-tree/)”
- 5. “[617. 合并二叉树](https://leetcode-cn.com/problems/merge-two-binary-trees/)”
1. “226. 翻转二叉树”
翻转二叉树的主要思路就是交换节点的左子树和右子树
递归:
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
TreeNode left = invertTree(root.left);
TreeNode right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
}
}
迭代:
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return root;
}
Deque<TreeNode> stack = new LinkedList<>();
TreeNode preHead = root;
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
TreeNode temp = cur.left;
cur.left = cur.right;
cur.right = temp;
if (cur.left != null) {
stack.push(cur.left);
}
if (cur.right != null) {
stack.push(cur.right);
}
}
return preHead;
}
}
2. “105. 从前序与中序遍历序列构造二叉树”
根据前序和中序遍历构造二叉树就是前序数组中从前往后看,第一个数组元素就是二叉树的根节点,在中序遍历中找到该节点的位置,左边就是左子树,右边就是右子树,依次类推。
class Solution {
private Map<Integer, Integer> inorderMap = new HashMap<Integer, Integer>();
private int[] preorder;
private int[] inorder;
private int p;
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
this.inorder = inorder;
this.p = 0;
buildInorder();
return build(0, preorder.length);
}
private TreeNode build(int lo, int hi) {
if (lo > hi || p > preorder.length - 1) {
return null;
}
int target = preorder[p++];
int targetIndex = inorderMap.get(target);
TreeNode left = build(lo, targetIndex - 1);
TreeNode right = build(targetIndex + 1, hi);
TreeNode newNode = new TreeNode(target);
newNode.left = left;
newNode.right = right;
return newNode;
}
private void buildInorder() {
for (int i = 0; i < inorder.length; i++) {
inorderMap.put(inorder[i], i);
}
}
}
3. " 从中序与后序遍历序列构造二叉树"
根据中序和后序遍历构造二叉树就是后序数组中从后往前看,第一个数组元素就是二叉树的根节点,在中序遍历中找到该节点的位置,左边就是左子树,右边就是右子树,依次类推。
class Solution {
private Map<Integer, Integer> inorderMap = new HashMap<Integer, Integer>();
private int[] inorder;
private int[] postorder;
private int p;
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.inorder = inorder;
this.postorder = postorder;
this.p = postorder.length - 1;
buildInorderMap();
return build(0, inorder.length - 1);
}
private TreeNode build(int lo, int hi) {
if (lo > hi || p < 0) {
return null;
}
int target = postorder[p--];
int targetIndex = inorderMap.get(target);
TreeNode right = build(targetIndex + 1, hi);
TreeNode left = build(lo, targetIndex - 1);
TreeNode newNode = new TreeNode(target);
newNode.left = left;
newNode.right = right;
return newNode;
}
private void buildInorderMap() {
for (int i = 0; i < inorder.length; i++) {
inorderMap.put(inorder[i], i);
}
}
}
4. “654. 最大二叉树”
每次都从区间找最大的值的下标,然后在根据下标去构建二叉树
class Solution {
private int[] nums;
public TreeNode constructMaximumBinaryTree(int[] nums) {
this.nums = nums;
return build(0, nums.length - 1);
}
private TreeNode build(int lo, int hi) {
if (lo > hi) {
return null;
}
int targetIndex = findMaxIndex(lo, hi);
TreeNode left = build(lo, targetIndex - 1);
TreeNode right = build(targetIndex + 1, hi);
TreeNode newNode = new TreeNode(nums[targetIndex]);
newNode.left = left;
newNode.right = right;
return newNode;
}
private int findMaxIndex(int lo, int hi) {
int max = Integer.MIN_VALUE;
int index = 0;
for (int i = lo; i <= hi; i++) {
if (nums[i] > max) {
index = i;
max = nums[i];
}
}
return index;
}
}
5. “617. 合并二叉树”
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if (root1 == null && root2 == null) {
return null;
}
if (root1 == null) {
return root2;
}
if (root2 == null) {
return root1;
}
TreeNode left = mergeTrees(root1.left, root2.left);
TreeNode right = mergeTrees(root1.right, root2.right);
TreeNode newNode = new TreeNode(root1.val + root2.val);
newNode.left = left;
newNode.right = right;
return newNode;
}
}