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

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

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

    例如,给出

    中序遍历 inorder = [9,3,15,20,7]
    后序遍历 postorder = [9,15,7,20,3]

    返回如下的二叉树:

        3
       / 
      9  20
        /  
       15   7



    一开始我没有理解构造一棵树的意思,之前这一类的题,我接触到的都是返回某一种遍历顺序的数组,后来参考他人的解答,
    才知道构建一棵树,其实就是通过链表形式构建一棵树,返回根结点
    解决树的问题,基本思维是用递归的方法
    中序遍历:
    1. 访问根结点
    2. 根节点的左结点进行中序遍历
    3. 根结点的右结点进行中序遍历

    后序遍历:

    1. 后序遍历根结点左子树
    2. 后序遍历根节点右子树
    3. 访问根结点

    树的遍历都是用递归的思维来实现的

    中序遍历 inorder = [9,3,15,20,7]
    后序遍历 postorder = [9,15,7,20,3]
    3
       / 
      9  20
        /  
       15   7
    通过观察遍历的结果可以发现,后序遍历最后遍历的是根结点,中序遍历中,根结点左边的
    是树的左子树,根节点右边的是树的右子树
    在这个例子中后序遍历的最后一个是3,那么在中序遍历中9是树的左子树,15,20,7是树的右子树
    根据上一步求到的左子树,和右子树的长度,再把后序遍历根据长度分为左子树,右子树。
    在进行和上面一样的遍历
    下面展示一下递归的实现过程
    递归的最开始是从inorder,postorder整个数组开始的
    dfs(inorder, postorder, 0, 4, 0, 4)
      root->val = postorder[4] = 9    #这个即为根节点的值,实现过程可以参考下面的程序
      i = 1;               #找到9在inorder中的位置
      root->left = dfs(inorder, postorder, 0, 0, 0, 0) #通过递归找到根结点的左结点
          root->val = postorder[0] = 9;
          i = 0;
    root->left = dfs(inorder, postorder, 0, -1, 0, -1)
                  return null;
        root->right = dfs(inorder, postorder,1, 0, 1, 0)
                  return null;
      root->right = dfs(inorder, postorder, 2, 4, 1, 3) #通过递归找到根结点的右结点
        root->val = postorder[3] = 20
        i = 3
        root->left = dfs(inorder, postorder, 2, 2, 1, 1)
          root->val = postorder[1] = 15
          i = 2;
          root->left = dfs(inorder, postorder, 2, 1, 1, 0)
                  return null;
          root->right = dfs(inorder, postorder, 3, 2, 2, 1)
                  return null;
        root->right = dfs(inorder, postorder, 4, 4, 2, 2)
          root->val = postorder[2] = 7
          i = 4;
          root->left = dfs(inorder, postorder, 4, 3, 2, 1)
                  return null
          root->right = dfs(inorder, postorder, 5, 4, 2, 1)
                  return null;
      return root;

    递归终止于左边序列大于右边序列
    大家按照上面的过程推导一次,就能大概的理解到由中序,遍历前序的方法了
     1 /**
     2  * Definition for a binary tree node.
     3  * struct TreeNode {
     4  *     int val;
     5  *     TreeNode *left;
     6  *     TreeNode *right;
     7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     8  * };
     9  */
    10 class Solution {
    11 public:
    12     TreeNode* dfs(vector<int>& inorder, vector<int>& postorder, int inl, int inr, int postl, int postr){
    13         if(inl > inr) return NULL;
    14         TreeNode* root = new TreeNode(postorder[postr]);
    15         int i = inl;
    16         while(inorder[i] != postorder[postr] && i < inr) i++;
    17         root->left = dfs(inorder, postorder, inl, i-1, postl, postl+i-inl-1);
    18         root->right = dfs(inorder, postorder, i+1, inr, postl+i-inl, postr-1);
    19         return root;
    20     }
    21     TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
    22         int l = inorder.size()-1;
    23         return dfs(inorder, postorder, 0, l, 0, l);
    24     }
    25 };
    有疑惑或者更好的解决方法的朋友,可以联系我,大家一起探讨。qq:1546431565
  • 相关阅读:
    private知识笔记
    finalize知识笔记
    java实现队列的练习
    测试知识笔记(2)
    static和final知识笔记
    测试知识笔记(1)
    overloading知识笔记
    windows Copssh + git 搭建git服务器
    Java Servlet规范
    身份证验证JS代码
  • 原文地址:https://www.cnblogs.com/mr-stn/p/8977619.html
Copyright © 2011-2022 走看看