刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com
106. 从中序与后序遍历序列构造二叉树
给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历, postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @author light
* @Description 从中序与后序遍历序列构造二叉树
*
* 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历,
* postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
* @create 2023-08-20 9:48
*/
public class BuildTreeTest {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] inorder=new int[n];
for (int i = 0; i < n; i++) {
inorder[i]=input.nextInt();
}
int[] postorder=new int[n];
for (int i = 0; i < n; i++) {
postorder[i]=input.nextInt();
}
TreeNode treeNode = buildTree(inorder, postorder);
System.out.println(LevelOrderTest.levelOrder(treeNode)); //层序遍历输出二叉树
}
public static Map<Integer,Integer> map;
public static TreeNode buildTree(int[] inorder, int[] postorder) {
map=new HashMap<>();
if(postorder.length==0||inorder.length==0){
return null;
}
//用map中存放中序数组的值和下标: key--inorder[i];value--i
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i],i);
}
//左闭右闭
return findNode(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
private static TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {
if(inBegin>inEnd||postBegin>postEnd){
return null;
}
int rootIndex=map.get(postorder[postEnd]); //找到后序数组最后一个元素在中序数组中的位置
int rootValue=inorder[rootIndex]; //找到结点值
TreeNode root=new TreeNode(rootValue); //构造节点
//保存中序左子树个数,用于确定后序数组个数
int lenOfLeft=rootIndex-inBegin;
//中左序 后左序
root.left=findNode(inorder,inBegin,rootIndex-1,postorder,postBegin,postBegin+lenOfLeft-1);
//中右序 后右序
root.right=findNode(inorder,rootIndex+1,inEnd,postorder,postBegin+lenOfLeft,postEnd-1);
return root;
}
}
105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder
和 inorder
,其中 preorder
是二叉树的先序遍历, inorder
是同一棵树的中序遍历,请构造二叉树并返回其根节点。
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @author light
* @Description 从前序与中序遍历序列构造二叉树
* @create 2023-08-20 11:00
*/
public class BuildTree2Test {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] preorder=new int[n];
for (int i = 0; i < n; i++) {
preorder[i]=input.nextInt();
}
int[] inorder=new int[n];
for (int i = 0; i < n; i++) {
inorder[i]=input.nextInt();
}
TreeNode treeNode=buildTree(preorder,inorder);
System.out.println(LevelOrderTest.levelOrder(treeNode)); //层序遍历输出二叉树
}
public static Map<Integer,Integer> map;
public static TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder.length==0||inorder.length==0){
return null;
}
map=new HashMap<>();
//用map中存放中序数组的值和下标: key--inorder[i];value--i
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i],i);
}
//左闭右闭
return findNode(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
private static TreeNode findNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {
if(preBegin>preEnd||inBegin>inEnd){
return null;
}
int rootIndex=map.get(preorder[preBegin]); //找到根节点在中序数组中的下标
int rootValue=inorder[rootIndex];
TreeNode root=new TreeNode(rootValue); //构造节点
int lenOfLeft=rootIndex-inBegin; // 保存中序左子树个数,用来确定前序数列的个数
//前左,中左
root.left=findNode(preorder,preBegin+1,preBegin+lenOfLeft,inorder,inBegin,rootIndex-1);
//前右,中由
root.right=findNode(preorder,preBegin+lenOfLeft+1,preEnd,inorder,rootIndex+1,inEnd);
return root;
}
}
654. 最大二叉树
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums
构建的 最大二叉树 。
输入: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 的节点。
- 空数组,无子节点。
import java.util.Scanner;
/**
* @author light
* @Description 最大二叉树
* @create 2023-08-21 13:54
*/
public class ConstructMaximumBinaryTreeTest {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] nums=new int[n];
for (int i = 0; i < n; i++) {
nums[i]=input.nextInt();
}
TreeNode treeNode = constructMaximumBinaryTree(nums);
System.out.println(LevelOrderTest.levelOrder(treeNode)); //层序遍历输出二叉树
}
public static TreeNode constructMaximumBinaryTree(int[] nums) {
if(nums.length==1){
return new TreeNode(nums[0]);
}
//左闭右闭
return findNode(nums,0, nums.length-1);
}
private static TreeNode findNode(int[] nums, int begin, int end) {
//递归终止条件
if(begin>end){
return null;
}
//数组中只有一个元素
if(end-begin==0){
return new TreeNode(nums[begin]);
}
int rootIndex=Integer.MIN_VALUE;
int rootValue=Integer.MIN_VALUE;
for (int i = begin; i <=end; i++) {
if(nums[i]>rootValue){
rootValue=nums[i]; //找到最大的根节点值
rootIndex=i;
}
}
TreeNode root=new TreeNode(rootValue);
root.left=findNode(nums,begin,rootIndex-1);
root.right=findNode(nums,rootIndex+1,end);
return root;
}
}