帮你从算法的角度来认识二叉树---(二)

引言

在上文中提到了前序遍历、中序遍历、后序遍历,其中有一类算法题离不开这三种遍历方式,就是从前序与中序遍历序列中构造出二叉树(反向推导)、从后序与中序遍历序列中构造出二叉树,那能不能从前序与后序遍历序列中构造出二叉树呢?答案是不能

原因:前序:根 → 左 → 右;中序:左 → 根 → 右;后序:左 → 右 → 根,在这三个序列里,只有中序能够把左右子树给分开,再搭配一个前序或后序把根节点找到,这样就能实现左子树、根节点、右子树的判别,这个知识点非常重要

算法题1

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

示例

思路

利用递归思想+哈希表来实现:

首先先确定根节点:前序数组的第一个元素就是当前子树的根;

在中序数组中顶为根节点:用哈希表提前存好中序数组的值->下标,实现O(1)快速查找,找到根后,左边所有元素 = 左子树,右边所有元素 = 右子树

计算左子树节点数量:根节点在中序数组的下标-中序左边界;

递归构建左右子树:根据刚才求得的左子树大小,把前序和中序都划分成:左子树区间、右子树区间,递归构建左右子树,再挂到当前根节点上;

递归终止条件:当前区间左边界>右边界,返回null

这里用到哈希表是因为可以直接定位到根节点的位置,降低了时间复杂度

代码

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private Map<Integer,Integer> indexMap;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int n=preorder.length;
        indexMap=new HashMap<Integer,Integer>();
        for(int i=0;i<n;i++){
            indexMap.put(inorder[i],i);
        }
        return myBuildTree(preorder,inorder,0,n-1,0,n-1);
    }

    public TreeNode myBuildTree(int[] preorder,int[] inorder,int preorder_left,int preorder_right,int inorder_left,int inorder_right){
        if(preorder_left>preorder_right){
            return null;
        }

        int preorder_root=preorder_left;
        //找到根节点在中序遍历的下标
        int inorder_root=indexMap.get(preorder[preorder_root]);

        TreeNode root=new TreeNode(preorder[preorder_root]);
        int size_left_subtree=inorder_root-inorder_left;

        //构造左子树
        root.left=myBuildTree(preorder,inorder,preorder_left+1,preorder_left+size_left_subtree,inorder_left,inorder_root-1);
        //构造右子树
        root.right=myBuildTree(preorder,inorder,preorder_left+size_left_subtree+1,preorder_right,inorder_root+1,inorder_right);
        return root;
    }
   
}

算法题2

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

示例

思路

和利用前序+中序实现二叉树的构建思路是完全一样的,只不过根节点在后序数组的最后一位,只需要在原来的基础上更换一下坐标即可

代码

java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private Map<Integer,Integer> indexMap;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        int n=inorder.length;
        indexMap=new HashMap<Integer,Integer>();
        for(int i=0;i<n;i++){
            indexMap.put(inorder[i],i);
        }
        return myBuildTree(inorder,postorder,0,n-1,0,n-1);
    }

    public TreeNode myBuildTree(int[] inorder,int[] postorder,int inorder_left,int inorder_right,int postorder_left,int postorder_right){
        if(postorder_left>postorder_right){
            return null;
        }
        int postorder_root=postorder_right;
        int inorder_root=indexMap.get(postorder[postorder_root]);

        TreeNode root=new TreeNode(postorder[postorder_root]);
        int size_left_subTree=inorder_root-inorder_left;

        root.left=myBuildTree(inorder,postorder,inorder_left,inorder_root-1,postorder_left,postorder_left+size_left_subTree-1);
        root.right=myBuildTree(inorder,postorder,inorder_root+1,inorder_right,postorder_left+size_left_subTree,postorder_right-1);
        return root;
    }
}

小舟有话说

这篇只讲了一种题型,下一篇还会讲一下其他剩余常见算法题~

相关推荐
手写码匠11 分钟前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc
无限码力35 分钟前
阿里算法岗 0530笔试真题 - 多约束条件下的元素匹配统计
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试
lqqjuly43 分钟前
MLA — 多头潜在注意力深度解析
深度学习·神经网络·算法
吴可可1231 小时前
SolidWorks草图转三维DWG技巧
算法
redaijufeng2 小时前
C++雾中风景7:闭包
c++·算法·风景
小欣加油2 小时前
leetcode287寻找重复数
数据结构·c++·算法·leetcode
尽兴-3 小时前
2.1 向量基础:Embedding、余弦相似度、欧氏距离、向量检索
算法·embedding·欧氏距离·向量检索·余弦相似度
Black蜡笔小新3 小时前
自动化AI算法训练服务器DLTM训推一体工作站赋能多行业智能化升级
人工智能·算法·自动化
怪兽学LLM3 小时前
LeetCode 438 找到字符串中所有字母异位词(Python 固定滑动窗口+字符计数解法)
python·算法·leetcode
满怀冰雪3 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法