zoukankan      html  css  js  c++  java
  • 【LeetCode】105. 从前序与中序遍历序列构造二叉树

    题目描述

    根据一棵树的前序遍历与中序遍历构造二叉树。

    注意:
    你可以假设树中没有重复的元素。

    例如,给出

    前序遍历 preorder = [3,9,20,15,7]
    中序遍历 inorder = [9,3,15,20,7]
    

    返回如下的二叉树:

        3
       / 
      9  20
        /  
       15   7
    

    题解思路

    代码

    class Solution {
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if(preorder.length==0||inorder.length==0){
                return null;
            }
            TreeNode root=new TreeNode (preorder[0]);
            for(int i=0;i<preorder.length;i++){
                if(preorder[0]==inorder[i]){
                    root.left=buildTree(Arrays.copyOfRange(preorder,1,i+1),Arrays.copyOfRange(inorder,0,i));
                    root.right=buildTree(Arrays.copyOfRange(preorder,i+1,preorder.length),Arrays.copyOfRange(inorder,i+1,inorder.length));
                    break;
                }
            }
            return root;
        }
    }
    
    /**
     * 首先要知道一个结论,前序/后序+中序序列可以唯一确定一棵二叉树,所以自然而然可以用来建树。
     * 看一下前序和中序有什么特点,前序1,2,4,7,3,5,6,8 ,中序4,7,2,1,5,3,8,6;
     * 有如下特征:
     * 前序中左起第一位1肯定是根结点,我们可以据此找到中序中根结点的位置rootin;
     * 中序中根结点左边就是左子树结点,右边就是右子树结点,即[左子树结点,根结点,右子树结点],我们就可以得出左
     * 子树结点个数为int left = rootin - leftin;;
     * 前序中结点分布应该是:[根结点,左子树结点,右子树结点];
     * 根据前一步确定的左子树个数,可以确定前序中左子树结点和右子树结点的范围;
     * 如果我们要前序遍历生成二叉树的话,下一层递归应该是:
     * 左子树:root->left = pre_order(前序左子树范围,中序左子树范围,前序序列,中序序列);;
     * 右子树:root->right = pre_order(前序右子树范围,中序右子树范围,前序序列,中序序列);。
     * 每一层递归都要返回当前根结点root;
     */
    class Solution {
    public:
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return pre_order(0, inorder.size() - 1, 0, inorder.size() - 1, preorder, inorder);
        }
        
        TreeNode *pre_order(int leftpre, int rightpre, int leftin, int rightin, vector<int> &pre, vector<int> &in) {
            if (leftpre > rightpre || leftin > rightin) return NULL;
            TreeNode *root = new TreeNode(pre[leftpre]);
            int rootin = leftin;
            while (rootin <= rightin && in[rootin] != pre[leftpre]) rootin++;
            int left = rootin - leftin;
            root->left = pre_order(leftpre + 1, leftpre + left, leftin, rootin - 1, pre, in);
            root->right = pre_order(leftpre + left + 1, rightpre, rootin + 1, rightin, pre, in);
            return root;
        }
    };
    

    题后感想

  • 相关阅读:
    iOS开发第三方库一 IQKeyboardManager
    跟着百度学PHP[14]-初识PDO数据库抽象层
    文件上传漏洞的一些总结
    逻辑漏洞挖掘入门之 简单的任意账户密码重置
    突破MIME限制上传
    关于Safe DOG的文件上传bypass
    跟着百度学PHP[13]-文件上传
    PHP flock() 函数 php中的文件锁定机制
    mysql变量
    一份不错的php面试题(附答案)(笔试题)
  • 原文地址:https://www.cnblogs.com/melodyjerry/p/12935919.html
Copyright © 2011-2022 走看看