zoukankan      html  css  js  c++  java
  • [LeetCode] 105. Construct Binary Tree from Preorder and Inorder Traversal 由先序和中序遍历建立二叉树

    Given preorder and inorder traversal of a tree, construct the binary tree.

    Note:
    You may assume that duplicates do not exist in the tree.

    For example, given

    preorder = [3,9,20,15,7]
    inorder = [9,3,15,20,7]

    Return the following binary tree:

        3
       / 
      9  20
        /  
       15   7

    这道题要求用先序和中序遍历来建立二叉树,跟之前那道 Construct Binary Tree from Inorder and Postorder Traversal 原理基本相同,针对这道题,由于先序的顺序的第一个肯定是根,所以原二叉树的根节点可以知道,题目中给了一个很关键的条件就是树中没有相同元素,有了这个条件就可以在中序遍历中也定位出根节点的位置,并以根节点的位置将中序遍历拆分为左右两个部分,分别对其递归调用原函数,参见代码如下:

    class Solution {
    public:
        TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
            return buildTree(preorder, 0, preorder.size() - 1, inorder, 0, inorder.size() - 1);
        }
        TreeNode *buildTree(vector<int> &preorder, int pLeft, int pRight, vector<int> &inorder, int iLeft, int iRight) {
            if (pLeft > pRight || iLeft > iRight) return NULL;
            int i = 0;
            for (i = iLeft; i <= iRight; ++i) {
                if (preorder[pLeft] == inorder[i]) break;
            }
            TreeNode *cur = new TreeNode(preorder[pLeft]);
            cur->left = buildTree(preorder, pLeft + 1, pLeft + i - iLeft, inorder, iLeft, i - 1);
            cur->right = buildTree(preorder, pLeft + i - iLeft + 1, pRight, inorder, i + 1, iRight);
            return cur;
        }
    };

    下面来看一个例子, 某一二叉树的中序和后序遍历分别为:

    Preorder:    5  4  11  8  13  9

    Inorder:    11  4  5  13  8  9

    5  4  11  8  13  9      =>          5

    11  4  5  13  8  9                /  

    4  11     8   13  9      =>         5

    11  4     13  8  9                  /  

                                 4   8

    11       13    9        =>         5

    11       13    9                    /  

                                 4   8

                                /    /    

                               11    13    9

    做完这道题后,大多人可能会有个疑问,怎么没有由先序和后序遍历建立二叉树呢,这是因为先序和后序遍历不能唯一的确定一个二叉树,比如下面五棵树:

        1      preorder:    1  2  3
       /        inorder:       2  1  3
     2    3       postorder:   2  3  1

           1       preorder:     1  2  3
          /       inorder:       3  2  1
        2          postorder:   3  2  1
       /
     3

           1        preorder:    1  2  3
          /        inorder:      2  3  1
        2       postorder:  3  2  1
         
           3

           1         preorder:    1  2  3
                     inorder:      1  3  2
              2      postorder:  3  2  1
             /
           3

           1         preorder:    1  2  3
                   inorder:      1  2  3
              2      postorder:  3  2  1
               
        3

    从上面我们可以看出,对于先序遍历都为 1 2 3 的五棵二叉树,它们的中序遍历都不相同,而它们的后序遍历却有相同的,所以只有和中序遍历一起才能唯一的确定一棵二叉树。但可能会有小伙伴指出,那第 889 题 Construct Binary Tree from Preorder and Postorder Traversal 不就是从先序和后序重建二叉树么?难道博主被啪啪打脸了么?难道博主的一世英名就此毁于一旦了么?不,博主向命运的不公说不,请仔细看那道题的要求 "Return any binary tree that matches the given preorder and postorder traversals.",是让返回任意一棵二叉树即可,所以这跟博主的结论并不矛盾。长舒一口气,博主的晚节保住了~

    Github 同步地址:

    https://github.com/grandyang/leetcode/issues/105

    类似题目:

    Construct Binary Tree from Inorder and Postorder Traversal

    Construct Binary Tree from Preorder and Postorder Traversal

    参考资料:

    https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

    https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/discuss/34538/My-Accepted-Java-Solution

    https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/discuss/34562/Sharing-my-straightforward-recursive-solution

    LeetCode All in One 题目讲解汇总(持续更新中...) 

  • 相关阅读:
    ios 常用的数学函数
    iOS已发布应用中对异常信息捕获和处理
    iOS 制作framework步骤
    iOS 静态库和动态库.a和framework
    C#实现发送和接收pop3邮件方法
    C#实现给手机发送短信
    C#DataTable DataSet DataRow区别详解
    gridview合并相同的行
    ASP.NET导出EXCEl方法使用EXCEl对象
    ASP.NET导出EXCEl方法使用COM.EXCEL不使用EXCEl对象
  • 原文地址:https://www.cnblogs.com/grandyang/p/4296500.html
Copyright © 2011-2022 走看看