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

    题目要求

     

    算法分析

    先序遍历中第一个元素的值就是树的根,

    我们可以通过该值检索到根在中序遍历内对应的索引

     这样就得到了左子树的中序遍历,和左子树的长度。 以及右子树的中序遍历。

    在先序遍历序列中,根据左子树的长度,可以获得左子树的先序遍历,以及右子树的先序遍历。

     这样我们得到了左子树的先序遍历和中序遍历, 以及右子树的先序遍历和中序遍历。

    想要构建树,我们需要三样东西,构建左子树构建右子树

    现在我们有了根,还需要构建左子树和右子树。

    而我们已经得到了左右子树对应的先序遍历和中序遍历,这样就回归了题目要求:从前序和中序遍历序列构造二叉树。

    于是我们可以用递归实现该问题。

    只需要找到需要构建的树的长度,以及树在先序和中序遍历序列中左边界的索引,

    就可以用以上规律递归构建树。

    代码展示(C#)

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     public int val;
     *     public TreeNode left;
     *     public TreeNode right;
     *     public TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        //用于存储中序遍历序列数据的字典,key为序列的数值,value为数值对应的索引
        public Dictionary<int, int> dicInoder = new Dictionary<int, int>();
    
        
        public TreeNode BuildTree(int[] preorder, int[] inorder)
        {
            int preorderLeft, inorderLeft ,treeLength;
    
            preorderLeft = 0;   //当前树的先序遍历序列的左边界索引
            inorderLeft = 0;    //当前树的中序遍历序列的左边界索引
            treeLength = preorder.Length;   //当前树的长度
    
            //创建字典存储中序遍历序列的数据
            for (int i = 0; i < treeLength; ++i)
            {
                dicInoder.Add(inorder[i], i);
            }
            //用于检索中序遍历序列中分隔左右子树的索引
    
    
            return CreateTree(preorder, preorderLeft, inorderLeft, treeLength);
        }
    
        /// <summary>
        /// 创建树(递归程序)
        /// </summary>
        /// <param name="preorder">先序遍历序列</param>
        /// <param name="preorderLeft">先序遍历序列内用来构造树的区间的左边界索引</param>
        /// <param name="inorderLeft">中序遍历序列内用来构造树的区间的左边界索引</param>
        /// <param name="treeLength">树的长度</param>
        /// <returns></returns>
        public TreeNode CreateTree(int[] preorder, int preorderLeft, int inorderLeft, int treeLength)
        {
            //树的长度不足1返回空树
            if (treeLength < 1)
            {
                return null;
            }
    
            int val = preorder[preorderLeft];   //获取先序遍历区间左边界的值
            int centerIndex = dicInoder[val];   //通过val在字典中查找中序遍历序列中分隔左右子树的索引
            int treeLengthLeft = centerIndex - inorderLeft; //左子树的长度
            int treeLengthRight = treeLength - treeLengthLeft - 1;  //右子树的长度
    
            //节点的值
            TreeNode treeNode = new TreeNode(val);  
            //创建左子树
            treeNode.left = CreateTree(preorder, preorderLeft + 1, inorderLeft, treeLengthLeft);
            //创建右子树
            treeNode.right = CreateTree(preorder,preorderLeft+treeLengthLeft+1, centerIndex + 1, treeLengthRight);
    
            return treeNode;
        }
    }

    代码展示(C++)

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        unordered_map<int, int> map;
    
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            int preorderLeft, inorderLeft, treeLength;
            preorderLeft = 0;
            inorderLeft = 0;
            treeLength = preorder.size();
    
            for (int i = 0; i < treeLength; ++i) {
                map[inorder[i]] = i;
            }
            
            return CreateTree(preorder, preorderLeft, inorderLeft, treeLength);
        }
    
    
        TreeNode* CreateTree(vector<int>& preorder, int preorderLeft, int inorderLeft, int treeLength) {
            if (treeLength < 1) {
                return NULL;
            }
    
            int val = preorder[preorderLeft];
            TreeNode* treeNode = new TreeNode(val);
            int centerIndex = map[val];
            int leftTreeLength = centerIndex - inorderLeft;
            int rightTreeLength = treeLength - leftTreeLength - 1;
    
            treeNode->left = CreateTree(preorder, preorderLeft + 1, inorderLeft, leftTreeLength);
            treeNode->right = CreateTree(preorder, preorderLeft + leftTreeLength + 1, centerIndex + 1, rightTreeLength);
    
            return treeNode;
        }
    };
    C++(无注释)

    提交结果

     

  • 相关阅读:
    [Objective-C语言教程]继承(25)
    [Objective-C语言教程]类和对象(24)
    [Objective-C语言教程]命令行参数(23)
    [Objective-C语言教程]错误处理(22)
    [Objective-C语言教程]日志处理(21)
    转 路径中 斜杠/和反斜杠 的区别
    转 Oracle 12C 之 CDB/PDB用户的创建与对象管理
    win10怎么启用网络发现,网络发现已关闭怎么办
    转 Oracle12c/11个 Client安装出现"[INS-30131]"错误“请确保当前用户具有访问临时位置所需的权限”解决办法之完整版
    转 Oracle DBCA高级玩法:从模板选择、脚本调用到多租户
  • 原文地址:https://www.cnblogs.com/KingR/p/12937183.html
Copyright © 2011-2022 走看看