題目:
試題 算法訓練 繪制地圖
資源限制
時間限制:1.0s 內存限制:256.0MB
問題描述
最近,WYF正准備參觀他的點卡工廠。WYF集團的經理氰垃圾需要幫助WYF設計參“觀”路線。現在,氰垃圾知道一下幾件事情:
1.WYF的點卡工廠構成一顆二叉樹。
2.一共有n座工廠。
3.他需要把這顆樹上的點以后序遍歷的方法列出來,才能繪制地圖。
還好,最近他的屬下給了他先序遍歷和中序遍歷的數據。可是,氰垃圾最近還要幫㊎澤穻解決一些問題,沒有時間。請你幫幫他,替他完成這項任務。由於氰垃圾的一些特殊的要求,WYF的參觀路線將會是這棵樹的后序遍歷。
1.WYF的點卡工廠構成一顆二叉樹。
2.一共有n座工廠。
3.他需要把這顆樹上的點以后序遍歷的方法列出來,才能繪制地圖。
還好,最近他的屬下給了他先序遍歷和中序遍歷的數據。可是,氰垃圾最近還要幫㊎澤穻解決一些問題,沒有時間。請你幫幫他,替他完成這項任務。由於氰垃圾的一些特殊的要求,WYF的參觀路線將會是這棵樹的后序遍歷。
輸入格式
第一行一個整數n,表示一共又n座工廠。
第二行n個整數,表示先序遍歷。
第三行n個整數,表示中序遍歷。
第二行n個整數,表示先序遍歷。
第三行n個整數,表示中序遍歷。
輸出格式
輸出共一行,包含n個整數,為后序遍歷。
樣例輸入
8
1 2 4 5 7 3 6 8
4 2 7 5 1 8 6 3
1 2 4 5 7 3 6 8
4 2 7 5 1 8 6 3
樣例輸出
4 7 5 2 8 6 3 1
數據規模和約定
0<n<100000,。保證先序遍歷和中序遍歷合法,且均為1~n。
Java代碼:
package com.lzp.algorithmpractice.p13; import java.util.Scanner; /** * @Author LZP * @Date 2021/3/11 13:36 * @Version 1.0 * 試題 算法訓練 繪制地圖 資源限制 時間限制:1.0s 內存限制:256.0MB 問題描述 最近,WYF正准備參觀他的點卡工廠。WYF集團的經理氰垃圾需要幫助WYF設計參“觀”路線。現在,氰垃圾知道一下幾件事情: 1.WYF的點卡工廠構成一顆二叉樹。 2.一共有n座工廠。 3.他需要把這顆樹上的點以后序遍歷的方法列出來,才能繪制地圖。 還好,最近他的屬下給了他先序遍歷和中序遍歷的數據。可是,氰垃圾最近還要幫㊎澤穻解決一些問題,沒有時間。請你幫幫他,替他完成這項任務。由於氰垃圾的一些特殊的要求,WYF的參觀路線將會是這棵樹的后序遍歷。 輸入格式 第一行一個整數n,表示一共又n座工廠。 第二行n個整數,表示先序遍歷。 第三行n個整數,表示中序遍歷。 輸出格式 輸出共一行,包含n個整數,為后序遍歷。 樣例輸入 8 1 2 4 5 7 3 6 8 4 2 7 5 1 8 6 3 樣例輸出 4 7 5 2 8 6 3 1 數據規模和約定 0<n<100000,。保證先序遍歷和中序遍歷合法,且均為1~n。 采用二分策略,遞歸求解 */ public class Main { private static int[] front; private static int[] mid; private static int[] dp = new int[100000 + 10]; private static int n; public static void main(String[] args) { Scanner input = new Scanner(System.in); n = input.nextInt(); front = new int[n]; mid = new int[n]; for (int i = 0; i < n; i++) { front[i] = input.nextInt(); } for (int i = 0; i < n; i++) { int temp = input.nextInt(); mid[i] = temp; /* dp數組在這里的作用就是記錄中序遍歷序列中數的索引值,方 便后面直接通過數組下標獲取,不用每一次都要為了拿一個數 據而去遍歷整個中序遍歷序列 */ dp[temp] = i; } f(); } public static void f() { Node tree = division(dp[front[0]], 0, 0, n - 1); laterAccess(tree); } /** * 遞歸 * 這里的parent是為了找到根節點在中序遍歷序列中的索引,cur是在當前前序遍歷中指針指向的位置, * 它的傳入是在遞歸的過程中為了方便找左右孩子,start、end是兩個邊界的索引 * @param parent * @param cur * @param start * @param end * @return */ public static Node division(int parent, int cur, int start, int end) { // 遞歸的出口 if (start == end) { return new Node(mid[parent], null, null); } if (start > end) { return null; } Node left = null; Node right = null; if (cur + 1 >= 0) { // 找左孩子 left = division(dp[front[cur + 1]], cur + 1, start, parent - 1); } if (cur + 1 + (parent - start) < n) { // 找右孩子 right = division(dp[front[cur + 1 + (parent - start)]], cur + 1 + (parent - start), parent + 1, end); } // 創建並返回父親節點 return new Node(mid[parent], left, right); } /** * 后序遍歷 * @param tree 樹的根節點 */ public static void laterAccess(Node tree) { if (tree != null) { laterAccess(tree.left); laterAccess(tree.right); System.out.print(tree.data + " "); } } } class Node { int data; Node left; Node right; public Node(int data, Node left, Node right) { this.data = data; this.left = left; this.right = right; } }