zoukankan      html  css  js  c++  java
  • 【07】(难)根据前序,中序遍历重建二叉树

    题目

    输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
    input :
    前序遍历 preorder = [3,9,20,15,7]
    中序遍历 inorder = [9,3,15,20,7]

    思路

    这道题我不会做,看了题解之后,才发现有迹可循。可以使用递归。
    具体思路我会在代码中注释

    收获

    递归重建二叉树

    代码中。右子树的第一个参数(右子树根节点在前序遍历数组中的索引)为:
    原根节点的索引(pre_root)+左子树长度(原根节点在中序遍历中数组的索引 - 左边界 = in_root-left) +1;

    代码:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        HashMap<Integer,Integer>dict=new HashMap<>();//用于储存中序遍历
        int po[];//因为代码思路通过索引取值,所以需要两个全局变量
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            po = preorder;
            //为什么要存储中序数组?
            //因为有一部需要查前序遍历中的根节点在中序遍历中的位置,以此划分左右子树
            for(int i=0;i<po.length;i++) 
                dict.put(inorder[i],i);
            return recur(0,0,inorder.length-1);
        }
    
        public TreeNode recur(int pre_root,int in_left,int in_right){
            //递归退出条件为左大右
            if(in_left>in_right) return null;
            var ans = new TreeNode(po[pre_root]);
            //由前序遍历得到的根节点,查到该节点在中序遍历内的索引,即可借此在中序遍历中划分出左右子树。
            int in_root = dict.get(po[pre_root]);
    
            //在in_left,in_root,in_right中划分
            //左子树
            ans.left = recur(pre_root+1,in_left,in_root-1);
    
            //右子树的根节点为 原根节点 + 左子树长度 + 1
            ans.right=recur(in_root-in_left+pre_root+1,in_root+1,in_right);
            return ans;
        }
    }
    
    
    个人小站:http://jun10ng.work/ 拥抱变化,时刻斗争,走出舒适圈。
  • 相关阅读:
    nginx访问控制
    nginx的请求限制
    nginx目录及配置语法
    安装Nginx
    Docker Service启动时挂载docker命令
    禁止flyme自动下载rom
    docker.service 修改指南
    debian 10.x (buster) 离线安装docker及卸载
    按照容器名称清除docker容器产生的日志文件内容
    debian修改系统语言为英文
  • 原文地址:https://www.cnblogs.com/Jun10ng/p/12345257.html
Copyright © 2011-2022 走看看