刷题之完全二叉树的权值和小字辈及根据后序和中序遍历输出先序遍历
创始人
2024-03-01 18:23:11

1、完全二叉树的权值

1)题目

给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A1, A2, ··· AN,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。

注:根的深度是 1。

输入格式:

第一行包含一个整数 N(1≤N≤10^5)。

第二行包含 N 个整数 A1, A2, ··· AN (−10^5 <= Ai<=10^5)。

输出格式:

输出一个整数代表答案。

输入样例:

在这里给出一组输入。例如:

7
1 6 5 4 3 2 1

输出样例:

在这里给出相应的输出。例如:

2

 2)题目解析

 题目要求我们输入n个数字,这n个数字是一颗树的层序遍历,并且这是一颗完全二叉树。计算哪一层数字之和最大,并输出该层数。注:根的深度是 1。

 3)代码 

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();long []arr= new long[n];for (int j=0;j

 2、小字辈

1)题目

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。

输入格式:

输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。

输出格式:

首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。

输入样例:

9
2 6 5 5 -1 5 6 4 7


输出样例:

4
1 9

 2)题目解析

 题目要求我们输入N个数,这N个数表示从1到N的其父节点编号,家谱中辈分最高的老祖宗对应的父/母编号为 -1,然后找出其最小辈的编号。输入样例对应图如下图,可以帮助你们更好理解。

 

 3)代码

import java.util.*;public class Main1 {//L表示当前递归到的最大层数static int L;//使用队列来存储结果,先进先出static Queue queue=new LinkedList<>();//递归函数static void sonTree(int []arr,int father,int l){for (int i=1;iL){//如果当前递归的l大于L(当前递归到的最大层数),即是新的最大递归层数,// 清空队列,重新添加元素    L=l;queue.clear();}queue.add(father);}public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int []arr=new int[n+1];int x=0; //x表示-1祖宗的编号for (int i=1;i<=n;i++){arr[i]=sc.nextInt();//记录祖宗的编号if (arr[i]==-1)x=i;}//从1楼开始int l=1;sonTree(arr,x,l);System.out.println(L);while (queue.size()!=1){System.out.print(queue.poll()+" ");}System.out.print(queue.poll());}
}

 上述代码是递归方法,但是因为题目数据量过大,N(不超过 100 000 的正整数),因此部分题给用例会超时或者其他错误,欢迎大佬在评论区给出建议。下面是正确的另一种方法:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {public static void main(String[] args) throws IOException {//因为题目数据用量特别大,所以用BufferedReader,提高数据读取时间BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));int n=Integer.parseInt(bf.readLine());//因为所给数据是每个人的父母,所以用arr[]来存放第i人的子女ArrayList arr[]=new ArrayList[n+1];for (int i=0;i();}int[] count=new int[n+1];//存放每个人的辈分Queue q=new LinkedList<>();//层序遍历来求辈分//如果只有一个人直接输出if (n==1){System.out.println(1);System.out.print(1);return;}//读取n个数据String s=bf.readLine();String[] ss=s.split(" ");int x=0;int lzz=0;//记录老祖宗的编号for (int i=1;i<=n;i++){x= Integer.parseInt(ss[i-1]);//记录祖宗的编号if (x==-1)lzz=i;else//将i加入到该第x个ArrayList集合中,表示第i个人是第x个人的子女,arr[x].add(i);}//先将老祖宗入队q.add(lzz);int L=1;//表示辈分count[lzz]=1;//老祖宗的辈分是1while (!q.isEmpty()){int t=q.peek();q.poll();for (int i=0;i

 为了更好理解可以看看下面图,先找到5的子女并放入arr[x]中。子女的辈分值为 二,然后在count[]的相应位置存储其辈分值。然后再找3,4,6的子女并放入3,4,6对应的arr[]中,其对应的子女的辈分值为3·· ···

L为最大的辈分值,即是最小辈分,然后去count[]数组中找与L相等的辈分值,并输出其对应的i值。

 

 3、根据后序和中序遍历输出先序遍历

1)题目

本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。

输入格式:

第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。

输出格式:

在一行中输出Preorder: 以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。

输入样例:

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

输出样例:

Preorder: 4 1 3 2 6 5 7

 2)题目解析

题目给定我们N个数,然后在下两行分别给出由这N个数组成的一颗二叉树的后序遍历和中序遍历。然后要求我们输出前序遍历。我们应该先根据后序遍历和中序遍历,构建出这颗二叉树,然后再进行前序遍历并输出。

 3)代码

import java.util.*;public class Main {public static class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int val) {this.val = val;}
}public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int []hx=new int[n];int []qx=new int[n];for (int i=0;i list=new ArrayList<>();preorder(tree,list);int j=0;System.out.print("Preorder: ");while (j!=list.size()-1){System.out.print(list.get(j)+" ");j++;}System.out.print(list.get(j));
}//前序遍历,使用List 集合存储public static void preorder(TreeNode root, Listlist){if (root == null) {return;}list.add(root.val);preorder(root.left, list);preorder(root.right, list);}//前序遍历public static void preOrder(TreeNode head) {if (head == null) {return;}System.out.print(head.val + " ");preOrder(head.left);preOrder(head.right);}static int index = 0;//构建二叉树public static TreeNode buildTree(int[] inorder, int[] postorder) {index = postorder.length-1;return buildTree(postorder, inorder, 0, inorder.length);}// index不断在后序遍历中找根节点,每次找完之后,根据找到的根节点将中序遍历分成//左右两部分,左侧为根的左子树,右侧为根的右子树// 注意:与前序中序还原二叉树不同的是,此次需要先还原右子树private static TreeNode buildTree(int[] postorder, int[] inorder, int left,int right){//如果left>=right,即左右节点遍历到同一节点,这时就要停止递归if(left >= right){return null;}// 创建根节点TreeNode root = new TreeNode(postorder[index]);// 在中序遍历结果中找到根的位置int rootIdx = left;//寻找根位置while(rootIdx < right){if(inorder[rootIdx] == postorder[index])break;rootIdx++;}index--;//要先构建右子树,再构建左子树,这是由后序遍历决定的//[rootIdx+1, right): 右子树中的所有节点的范围// 递归创建根的右子树root.right = buildTree(postorder, inorder, rootIdx+1, right);//[left, rootIdx):左子树中的所有节点的范围// 递归创建根的左子树root.left = buildTree(postorder, inorder, left, rootIdx);return root;}
}

其实根据后序和中序写出前序 和根据前序和中序写出后序是差不多的,只不过是从前往后遍后序,先构建左子树,过程都是差不多的。希望可以用帮助到大家。

 👍👍👍看到这里了还不点个赞👍👍👍

 

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...