1. 程式人生 > >(拼多多筆試演算法)根據二叉樹的前序遍歷和中序遍歷確定後序遍歷的兩種思路

(拼多多筆試演算法)根據二叉樹的前序遍歷和中序遍歷確定後序遍歷的兩種思路

根據二叉樹的前序遍歷和中序遍歷確定後序遍歷

輸入:第一行:結點數目
第二行:前序遍歷陣列
第三行:中序遍歷陣列
輸出 :後序遍歷陣列

例如:第一行:7
第二行:6 4 2 5 3 1 7
第三行:4 2 5 6 1 3 7
輸出 :5 2 4 1 7 3 6

我思考出來兩種方法

1、根據二叉樹的前序遍歷和中序遍歷還原二叉樹,然後進行後序遍歷

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public
class Main { static List<Integer> list=new ArrayList<>(); public static void main(String[] args) { Scanner scanner=new Scanner(System.in); int n=scanner.nextInt(); int pre[]=new int[n]; int order[]=new int[n]; int post[]=new int[n]; for
(int i = 0; i < pre.length; i++) { pre[i]=scanner.nextInt(); } for (int i = 0; i < order.length; i++) { order[i]=scanner.nextInt(); } scanner.close(); TreeNode node=reConstructBinaryTree(pre, order); postOrder(node); for
(int i = 0; i < list.size(); i++) { post[i]=list.get(i); } for (int i = 0; i < post.length; i++) { System.out.print(post[i]); if(i!=post.length-1) System.out.print(" "); } } //劍指offer提供思路 public static TreeNode reConstructBinaryTree(int [] pre,int [] in) { if(pre.length == 0||in.length == 0){ return null; } TreeNode node = new TreeNode(pre[0]); for(int i = 0; i < in.length; i++){ if(pre[0] == in[i]){ node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i)); node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length)); } } return node; } //後序遍歷 public static void postOrder(TreeNode node ) { if(node!=null) { postOrder(node.left); postOrder(node.right); list.add(node.val); } } // 6 4 2 5 3 1 7 // 4 2 5 6 1 3 7 } class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } }

缺點:時間複雜度太高(重建二叉樹遞迴,後序遍歷遞迴)
空間複雜度太高(二叉樹 ,List )

2、根據二叉樹的遍歷特點進行求解

前序遍歷:左根右 6 4 2 5 3 1 7
中序遍歷:左根右 4 2 5 6 1 3 7
後序遍歷:左右根 5 2 4 1 7 3 6

**由此可以看出,前序遍歷的第一個節點,是後序遍歷的最後一個節點
前序遍歷的第一個節點,在中序遍歷中將樹一分為2,
即根節點 6,左子樹 4 2 5,右子樹 1 3 7,繼續向下遞迴即可**

//坑爹啊,調程式除錯到現在,遞迴程式太難除錯



import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub


        Scanner scanner=new Scanner(System.in);

        int n=scanner.nextInt();

        int pre[]=new int[n];
        int order[]=new int[n];
        int post[]=new int[n];

        for (int i = 0; i < pre.length; i++) {
            pre[i]=scanner.nextInt();
        }
        for (int i = 0; i < order.length; i++) {
            order[i]=scanner.nextInt();
        }

        coverTree(pre,order,post,post.length-1);


        for (int i = 0; i < post.length; i++) {
            System.out.print(+post[i]);
            if(i!=post.length-1)System.out.print(" ");
        }




    }

    private static void coverTree(int[] pre, int[] order, int[] post, int i) {
        for (int j = 0; j < order.length; j++) {
            if(order[j]==pre[0]) {
//賦值
                    post[i]=order[j];

                //前面
                coverTree(Arrays.copyOfRange(pre, 1, j+1), Arrays.copyOfRange(order, 0, j),post,i-j-1);


//筆試的時候這塊一直有問題,調了一個小時才調出來,多除錯遞迴程式啊  ,血琳琳的教訓
/*
之前  前面寫的是是
coverTree(Arrays.copyOfRange(pre, 1, j+1), Arrays.copyOfRange(order, 0, j),post,j-1);因為j一直在變啊,沒體會出來,需要改成i-j-1

*/



                //後面

                coverTree(Arrays.copyOfRange(pre, j+1, pre.length), Arrays.copyOfRange(order, j+1,order.length),post,i-1);

            }
        }

    }





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





}

多思考思考第二種方法 還是可以想出來的~~~