LeetCode 105. 从前序与中序遍历序列构造二叉树, 106. 从中序与后序遍历序列构造二叉树

  1. 如何记住前中后序的遍历顺序:
    前序:中左右, 中序:左中右, 后续:左右中。
    观察发现,这个前中后序就是"中"所在的位置。
  2. 首先明确一点:前序和中序以及后序和中序都可以确定一棵二叉树,然而前序和后序却不能,为什么呢?因为我们只有知道中序才可以知道左子树,右子树的位置,才可以区分开来。从而还原一棵二叉树。
  3. 那么105,106两题就可以做了,题中有说到,节点的值都是不相等的,所以可以确定唯一一颗二叉树。

具体解题思路可以观看代码随想录题解,本文不再进行搬运,而是分析一些问题。

大概分为以下几步:

第一步:如果数组大小为零的话,说明是空节点了。

第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

第五步:切割后序数组,切成后序左数组和后序右数组

第六步:递归处理左区间和右区间

  1. Java对于数组的操作不是很灵活,需要转成ArrayList<>的形式,才会有indexOf之类的操作。
    所以我们用HashMap来进行index。
  2. 边界问题:
    1. 如果传入的是size-1,结束判断没有等号。所谓的左开右闭应当如此。
    2. 递归过程中,End也应该是End,不应该-1。
    3. index应该取index-1,index+1不应包含index。

105. 从前序与中序遍历序列构造二叉树

java 复制代码
class Solution {
    HashMap<Integer, Integer> inordermap = new HashMap<>();
    int[] pre;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        for (int i = 0; i < inorder.length; i++) {
            inordermap.put(inorder[i], i);
        }
        pre = preorder;
        TreeNode root = dfs(0, preorder.length - 1, 0, inorder.length - 1);
        return root;
    }

    private TreeNode dfs(int preStart, int preEnd, int inStart, int inEnd) {
        if (preEnd < preStart || inEnd < inStart) return null;
        int root = pre[preStart];
        int index = inordermap.get(root);
        
        TreeNode node = new TreeNode(root);
        node.left = dfs(preStart + 1, preStart + index - inStart, inStart, index - 1);
        node.right = dfs(preStart + index - inStart + 1, preEnd, index + 1, inEnd);
        return node;
    }
}

106. 从中序与后序遍历序列构造二叉树

java 复制代码
class Solution {
    HashMap<Integer, Integer> inordermap = new HashMap<>();
    int[] post;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        for (int i = 0; i < inorder.length; i++) {
            inordermap.put(inorder[i], i);
        }
        post = postorder;
        TreeNode root = dfs(0, inorder.length - 1, 0, post.length - 1);
        return root;
    }

    public TreeNode dfs(int inorderStart, int inorderEnd, int postorderStart, int postorderEnd) {
        if (inorderEnd < inorderStart || postorderEnd < postorderStart) {
            return null;
        }
        int root = post[postorderEnd];
        int index = inordermap.get(root);

        TreeNode node = new TreeNode(root);
        node.left = dfs(inorderStart, index - 1, postorderStart, postorderStart + index - inorderStart - 1);
        node.right = dfs(index + 1, inorderEnd, postorderStart + index - inorderStart, postorderEnd - 1);
        return node;
    }
}
相关推荐
九圣残炎24 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu29 分钟前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!1 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚1 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
sszmvb12341 小时前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
为什么这亚子2 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
2 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
~yY…s<#>2 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
测试界萧萧2 小时前
外包干了4年,技术退步太明显了。。。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展