(拼多多笔试算法)根据二叉树的前序遍历和中序遍历确定后序遍历的两种思路

根据二叉树的前序遍历和中序遍历确定后序遍历

输入:第一行:结点数目
第二行:前序遍历数组
第三行:中序遍历数组
输出 :后序遍历数组

例如:第一行: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





}

多思考思考第二种方法 还是可以想出来的~~~

点赞