W
e
l
c
o
m
e
: )

每日一题:根据先序、中序遍历数组构建二叉树

import java.util.HashMap;
import java.util.Map;

/**
 * 题目:根据给定的先序和中序遍历数组构造一颗二叉树(无重复节点)
 * 测试链接:https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
 */
public class ConstructBinaryTree {

    public static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int val) {
            this.val = val;
        }
    }

    /**
     * 构造二叉树,返回头节点
     * @param pre 先序数组
     * @param in 中序数组
     * @return
     */
    public static TreeNode buildTree(int[] pre,int[] in){
        //边界条件
        if (pre == null || in == null || pre.length != in.length){
            return null;
        }
//        return f1(pre,0,pre.length-1,in,0,in.length-1);
        //构建索引表
        Map<Integer,Integer> indexMap = new HashMap<>();
        for (int i=0;i<in.length;i++){
            indexMap.put(in[i],i);
        }
        return f2(pre,0,pre.length-1,in,0,in.length-1,indexMap);
    }

    /**
     * 递归函数
     * @param pre
     * @param L1
     * @param R1
     * @param in
     * @param L2
     * @param R2
     * @return
     */
    public static TreeNode f1(int[] pre,int L1,int R1,int[] in,int L2,int R2){
        /*
          比如先序是[1,2,3],中序也是[1,2,3],
          那么这棵树没有左半边,递归调用head.left的时候
          就会出现L1>R1的情况,直接返回null
         */
        if (L1 > R1){
            return null;
        }
        //先序的第一个节点必然是head节点
        TreeNode head = new TreeNode(pre[L1]);
        if (L1 == R1){
            //只有一个直接返回即可
            return head;
        }
        /*
         在中序数组内找到head的位置,那么左边就是它的左子树,右边就是它的右子树
        */
        int find = L2;
        while (in[find] != pre[L1]){
            find++;
        }
        head.left = f1(pre,L1+1,L1+find-L2,in,L2,find-1);
        head.right = f1(pre,L1+find-L2+1,R1,in,find+1,R2);
        return head;
    }

    /**
     * 递归函数(优化版)
     * @param pre
     * @param L1
     * @param R1
     * @param in
     * @param L2
     * @param R2
     * @param indexMap 中序数组每个数对应位置的索引表
     * @return
     */
    public static TreeNode f2(int[] pre, int L1, int R1, int[] in, int L2, int R2, Map<Integer,Integer> indexMap){
        if (L1 > R1){
            return null;
        }
        TreeNode head = new TreeNode(pre[L1]);
        if (L1 == R1){
            return head;
        }
        //此处替换为从索引表中获取位置
        int find = indexMap.get(pre[L1]);
        head.left = f2(pre,L1+1,L1+find-L2,in,L2,find-1,indexMap);
        head.right = f2(pre,L1+find-L2+1,R1,in,find+1,R2,indexMap);
        return head;
    }
}

posted @ 2026-08-03 10:14  寒月静无光  阅读(2)  评论(0)    收藏  举报