第十二届蓝桥杯省赛A组试题:左儿子右兄弟Java
【問題描述】
對于一棵多叉樹,我們可以通過 “左孩子右兄弟” 表示法,將其轉化成一棵二叉樹。如果我們認為每個結點的子結點是無序的,那么得到的二叉樹可能不唯一。換句話說,每個結點可以選任意子結點作為左孩子,并按任意順序連接右兄弟。給定一棵包含 N 個結點的多叉樹,結點從 1 至 N 編號,其中 1 號結點是根,每個結點的父結點的編號比自己的編號小。請你計算其通過 “左孩子右兄弟” 表示法轉化成的二叉樹,高度最高是多少。注:只有根結點這一個結點的樹高度為 0 。例如如下的多叉樹:
可能有以下 3 種 (這里只列出 3 種,并不是全部) 不同的 “左孩子右兄弟”表示:
其中最后一種高度最高,為 4。
【輸入格式】
輸入的第一行包含一個整數 N。
以下 N ?1 行,每行包含一個整數,依次表示 2 至 N 號結點的父結點編號。
【輸出格式】
輸出一個整數表示答案。
【樣例輸入】
5
1
1
1
2
【樣例輸出】
4
【評測用例規模與約定】
對于 30% 的評測用例,1 ≤ N ≤ 20;
對于所有評測用例,1 ≤ N ≤ 100000。
解題思路:①看到樹并且根據題意可以知道類似求最長路徑,可以使用深度優先搜索dfs算法,即找節點的孩子,再繼續找該孩子的孩子…直到沒有再回退。②可以使用一個ArrayList數組來存儲每個節點及其孩子(類似圖的鄰接表存儲),也就是說ArrayList數組的元素也是ArrayList,每個ArrayList元素存儲著該節點及其子孩子。
Java代碼:
import java.util.ArrayList; import java.util.Scanner;public class Tree {static int res = 0; //結果(最高樹高)static ArrayList<Integer>[] lists; //存儲節點及其子孩子(類似一個鄰接表)public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();lists = new ArrayList[n+1]; //后面我們是從下標1開始存儲,因此這里不要忘記+1//初始化(相當于填充進每個節點,數組下標即為該節點編號)for (int i = 1; i < n+1; i++) {lists[i] = new ArrayList<Integer>();}//構建鄰接表,將每個節點的孩子放到該下標的ArrayList里for (int i = 2; i < n+1; i++) {int node = scanner.nextInt();lists[node].add(i);}//從節點1(即根節點)開始dfs即可訪問全部,因為這是一棵樹dfs(0,1);System.out.println(res);}//深度優先搜索dfspublic static void dfs(int total, int father){//獲取當前節點孩子個數int size = lists[father].size();//如果當前節點沒有孩子,則重置res并返回if (size == 0) {res = Math.max(res,total);return;}//對該節點的孩子依次進行dfsfor (int temp : lists[father]){dfs(total+size,temp);}} }總結
以上是生活随笔為你收集整理的第十二届蓝桥杯省赛A组试题:左儿子右兄弟Java的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓3.5mm接口(安卓3.5)
- 下一篇: 第十二届蓝桥杯Java省赛A组试题:异或