• 剑指 Offer 07


    1 题目

    https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/

    2 题意

    输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

    例如,给出

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

    返回如下的二叉树:

        3
       / 
      9  20
        /  
       15   7
    

    限制:

    0 <= 节点个数 <= 5000

    3 解题思路

    author's blog == http://www.cnblogs.com/toulanboy/

    3.1 思考切入点

    主要利用遍历的特征解题,思考顺序如下:
    1、通过先序遍历,可知这棵树的根节点(第1个就是根节点)。
    2、通过中序遍历和根节点,由于根节点位于左右子树的中间,故可知左子树的中序遍历、右子树的中序遍历。
    3、通过第2步得出的左右子树中序遍历,可知左右子树的节点数。进一步地,结合整棵树先序遍历,可知左子树的先序遍历、右子树的先序遍历。
    通过上述3步,就可以分别知道左右子树的先序、中序遍历。循环这个逻辑,进一步细分,就可以还原整颗树。
    代码层面,利用递归就可以实现。

    3. 2 代码思路:

    1、递归步骤

    (1)通过先序得到这棵树的根节点。
    (2)左子树的根,调用相同逻辑得到。
    (3)右子树的根,调用相同逻辑得到。

    2、递归边界

    当先序遍历的序列为空,说明当前是个空树。

    4 代码实现

    //author's blog == http://www.cnblogs.com/toulanboy/
    /**
     * 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:
        //该树的先序遍历序列是preorder的[pre_left, pre_right]
        //该树的中序遍历序列是inorder的[in_left, in_right]
        TreeNode* build(vector<int>& preorder, int pre_left, int pre_right, vector<int>& inorder, int in_left, int in_right) {
            if(pre_left > pre_right){
                return NULL;
            }
            //先序遍历的第一个节点就是这棵树的根节点的数值
            TreeNode * root = new TreeNode(preorder[pre_left]);
            //通过根节点,结合中序遍历,找到左子树的节点数。
            int key = preorder[pre_left];
            int left_tree_count = 0;
            for(int i=in_left; i<=in_right; ++i){
                if(inorder[i] != key){
                    left_tree_count++;
                }
                else{
                    break;
                }
            }
            //知道左子树有多少个节点后,就可以进行具体的划分出左子树的先序遍历和中序遍历序列
            root->left = build(preorder, pre_left+1, pre_left+left_tree_count, inorder, in_left, in_left+left_tree_count-1);
            //原理同上
            root->right = build(preorder, pre_left+1+left_tree_count, pre_right, inorder, in_left+left_tree_count+1, in_right);
            return root;
        }
        TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
            return build(preorder, 0, preorder.size()-1, inorder, 0, inorder.size()-1);
        }
    };
    
  • 相关阅读:
    Java操作Redis的方式
    Redis综述
    KafKa综述
    NuxtJS项目——状态树
    NuxtJS项目——开发工具
    NuxtJS项目——命令和部署
    NuxtJS项目——模块
    NuxtJS项目——插件
    NuxtJS项目——资源文件
    Sampling Matrix
  • 原文地址:https://www.cnblogs.com/toulanboy/p/13686489.html
Copyright © 2020-2023  润新知