2022-1-8二叉树day2
题目1:
给定一个不含重复元素的整数数组 nums
。一个以此数组直接递归构建的 最大二叉树 定义如下:
- 二叉树的根是数组
nums
中的最大元素。 - 左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
- 右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
返回有给定数组 nums
构建的 最大二叉树 。
示例 1:
输入:nums = [3,2,1,6,0,5] 输出:[6,3,5,null,2,0,null,null,1] 解释:递归调用如下所示: - [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。 - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。 - 空数组,无子节点。 - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。 - 空数组,无子节点。 - 只有一个元素,所以子节点是一个值为 1 的节点。 - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。 - 只有一个元素,所以子节点是一个值为 0 的节点。 - 空数组,无子节点。
示例 2:
输入:nums = [3,2,1] 输出:[3,null,2,null,1]
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
nums
中的所有整数 互不相同
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public TreeNode constructMaximumBinaryTree(int[] nums) { 18 return construct(nums,0,nums.length-1); 19 } 20 21 public TreeNode construct(int[] nums,int l,int r){ 22 if (l>r) return null; 23 int max=-1,index=-1; 24 for (int i=l;i<=r;i++){ 25 if (nums[i]>max){ 26 max=nums[i]; 27 index=i; 28 } 29 } 30 TreeNode head=new TreeNode(max); 31 head.left=construct(nums,l,index-1); 32 head.right=construct(nums,index+1,r); 33 return head; 34 } 35 }
思路:遍历找出最大值,记录索引和最大值,新建头节点,再递归调用生成左子树和右子树。
题目2:
给定一棵树的前序遍历 preorder
与中序遍历 inorder
。请构造二叉树并返回其根节点。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1] Output: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder
和inorder
均无重复元素inorder
均出现在preorder
preorder
保证为二叉树的前序遍历序列inorder
保证为二叉树的中序遍历序列
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public TreeNode buildTree(int[] preorder, int[] inorder) { 18 return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1); 19 } 20 21 public TreeNode build(int[] preorder,int l1,int r1,int[] inorder,int l2,int r2){ 22 if (l1>r1||l2>r2) return null; 23 TreeNode root=new TreeNode(preorder[l1]); 24 int index=-1; 25 for (int i=l2;i<=r2;i++){ 26 if (inorder[i]==preorder[l1]){ 27 index=i; 28 break; 29 } 30 } 31 root.left=build(preorder,l1+1,l1+index-l2,inorder,l2,index-1); 32 root.right=build(preorder,l1+index-l2+1,r1,inorder,index+1,r2); 33 return root; 34 } 35 }
思路:根据前序遍历可以知道根节点,而对应在中序遍历中,左边与右边分别就是左子树和右子树的组成。
题3:
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public TreeNode buildTree(int[] inorder, int[] postorder) { 18 return build(inorder,0,inorder.length-1,postorder,0,postorder.length-1); 19 } 20 public TreeNode build(int[] inorder,int l1,int r1,int[] postorder,int l2,int r2){ 21 if (l1>r1||l2>r2) return null; 22 TreeNode root=new TreeNode(postorder[r2]); 23 int index=-1; 24 for (int i=l1;i<=r1;i++){ 25 if (inorder[i]==postorder[r2]){ 26 index=i; 27 break; 28 } 29 } 30 root.left=build(inorder,l1,index-1,postorder,l2 ,r2-r1+index-1); 31 root.right=build(inorder,index+1,r1,postorder,r2-r1+index ,r2-1); 32 return root; 33 } 34 }
思路:跟题2类似,区别在后后序遍历,根节点是最后那个节点。