力扣labuladong一刷day30天二叉樹
文章目錄
- 力扣labuladong一刷day30天二叉樹
- 一、654. 最大二叉樹
- 二、105. 從前序與中序遍歷序列構造二叉樹
- 三、106. 從中序與后序遍歷序列構造二叉樹
- 四、889. 根據前序和后序遍歷構造二叉樹
一、654. 最大二叉樹
題目鏈接:https://leetcode.cn/problems/maximum-binary-tree/
思路:采用分解問題的方法,先構造父節點再構造左右子節點,每次都在指定區間內搜索,找到最大值后構造父節點,再劃分左右區間遞歸。
class Solution {public TreeNode constructMaximumBinaryTree(int[] nums) {return traverse(nums, 0, nums.length - 1);}TreeNode traverse(int[] nums, int left ,int right) {if (left > right) return null;int max = -1, index = -1;for (int i = left; i <= right; i++) {if (nums[i] > max) {max = nums[i];index = i;}}TreeNode root = new TreeNode(max);root.left = traverse(nums, left, index-1);root.right = traverse(nums, index+1, right);return root;}
}
二、105. 從前序與中序遍歷序列構造二叉樹
題目鏈接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
思路:通過前序和中序構造二叉樹,要維護好前序的區間以及中序的區間,先構造父節點再構造左右子節點,父節點是前序區間的left,左右子節點由遞歸返回。 此外要注意速度,想節省遍歷中序數組尋找父節點索引的時間的話,可以使用map預先存儲下來。
class Solution {Map<Integer, Integer> map = new HashMap<>();public TreeNode buildTree(int[] preorder, int[] inorder) {for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return create(preorder, inorder, 0, preorder.length-1,0, inorder.length-1);}TreeNode create(int[] preorder, int[] inorder, int left1, int right1, int left2, int right2) {if (left1 > right1 || left2 > right2) return null;int midV = preorder[left1];TreeNode node = new TreeNode(midV);int index = map.get(midV);node.left = create(preorder, inorder, left1+1, left1+index-left2, left2, index-1);node.right = create(preorder, inorder, left1+index-left2+1, right1, index+1, right2);return node;}
}
三、106. 從中序與后序遍歷序列構造二叉樹
題目鏈接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/
思路:本題和上題類似,也是先構造父節點,然后再構造左右子節點,父節點由后續right構造,然后劃分中序和后序的區間,遞歸構造左右子樹。
class Solution {Map<Integer, Integer> map = new HashMap<>();public TreeNode buildTree(int[] inorder, int[] postorder) {for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return create(inorder, postorder, 0, inorder.length-1, 0, postorder.length-1);}TreeNode create(int[] inorder, int[] postorder, int left1, int right1, int left2, int right2) {if (left1 > right1 || left2 > right2) return null;int midV = postorder[right2];int index = map.get(midV);TreeNode node = new TreeNode(midV);node.left = create(inorder, postorder, left1, index-1, left2, left2+index-left1-1);node.right = create(inorder, postorder, index+1, right1, left2+index-left1, right2-1);return node;}
}
四、889. 根據前序和后序遍歷構造二叉樹
題目鏈接:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-postorder-traversal/
思路:通過前序和后序去構造二叉樹,構造的結果不唯一,但方法是一樣的,每次使用前序的left做為父節點,left+1做為左孩子的值,然后使用這個去后序中去劃分區間,然后在劃分前序遍歷的區間,之后遞歸構造即可。
class Solution {Map<Integer, Integer> map = new HashMap<>();public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {for (int i = 0; i < postorder.length; i++) {map.put(postorder[i], i);}return create(preorder, postorder, 0, preorder.length-1, 0, postorder.length-1);}TreeNode create(int[] preorder, int[] postorder, int left1, int right1, int left2, int right2) {if (left1>right1 || left2>right2) return null;if (left1 == right1) return new TreeNode(preorder[left1]);int mid = preorder[left1];int index = map.get(preorder[left1+1]);TreeNode node = new TreeNode(mid);node.left = create(preorder, postorder, left1+1, left1 + index-left2+1, left2,index);node.right = create(preorder, postorder, left1 + index-left2+2, right1,index+1, right2-1);return node;}
}