zoukankan      html  css  js  c++  java
  • leetcode

    题目:Construct Binary Tree from Inorder and Postorder Traversal

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

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

    题目: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.

    这两道题的思路是类似的,就放在一起说了,我就说第一个题目了,第二个可以用相同的方法做,就不赘述了。

    个人思路:

    1、先搞清中序遍历和后序遍历的特点,中序遍历:左、根、右,后序遍历:左、右、根,可以看出后序遍历的最后一个数就是根节点的值

    2、找到根节点后,可以根据根节点找出中序遍历和后序遍历中左子树节点和右子树节点的范围,然后按照相似的方法,找出左子树的根节点和右子树的根节点,它们也就是原树根节点的左右孩子,递归地往下进行即可构建完毕

    代码:

     1 #include <stddef.h>
     2 #include <vector>
     3 
     4 using namespace std;
     5 
     6 struct TreeNode
     7 {
     8     int val;
     9     TreeNode *left;
    10     TreeNode *right;
    11     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    12 };
    13 
    14 class Solution
    15 {
    16 public:
    17     TreeNode* buildTree(vector<int> &inorder, vector<int> &postorder)
    18     {
    19         return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);
    20     }
    21 private:
    22     TreeNode* build(vector<int> &inorder, vector<int> &postorder, int in_start, int in_end, int post_start, int post_end)
    23     {
    24         if (post_start > post_end)
    25         {
    26             return NULL;
    27         }
    28 
    29         TreeNode *root = new TreeNode(postorder[post_end]);
    30 
    31         //在中序遍历中找到根节点,以区分左子树和右子树
    32         int inorder_root;
    33         for (inorder_root = in_start; inorder_root <= in_end; ++inorder_root)
    34         {
    35             if (inorder[inorder_root] == postorder[post_end])
    36             {
    37                 break;
    38             }
    39         }
    40         //中序遍历中的左子树和右子树范围
    41         int inorder_left_start = in_start;
    42         int inorder_left_end = inorder_root - 1;
    43         int inorder_right_start = inorder_root + 1;
    44         int inorder_right_end = in_end;
    45         //后序遍历中的左子树和右子树范围
    46         int postorder_left_start = post_start;
    47         int postorder_left_end = post_start + (inorder_root - in_start) - 1;
    48         int postorder_right_start = postorder_left_end + 1;
    49         int postorder_right_end = post_end - 1;
    50 
    51         root->left = build(inorder, postorder, inorder_left_start, inorder_left_end, postorder_left_start, postorder_left_end);
    52         root->right = build(inorder, postorder, inorder_right_start, inorder_right_end, postorder_right_start, postorder_right_end);
    53 
    54         return root;
    55     }
    56 };
    View Code

    下面贴出第二道题的代码,算法类似第一题:

     1 #include <stddef.h>
     2 #include <vector>
     3 
     4 using namespace std;
     5 
     6 struct TreeNode
     7 {
     8     int val;
     9     TreeNode *left;
    10     TreeNode *right;
    11     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
    12 };
    13 
    14 class Solution
    15 {
    16 public:
    17     TreeNode* buildTree(vector<int> &preorder, vector<int> &inorder)
    18     {
    19         return build(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
    20     }
    21 private:
    22     TreeNode* build(vector<int> &preorder, vector<int> &inorder, int pre_start, int pre_end, int in_start, int in_end)
    23     {
    24         if (pre_start > pre_end)
    25         {
    26             return NULL;
    27         }
    28 
    29         TreeNode *root = new TreeNode(preorder[pre_start]);
    30 
    31         //在中序遍历中找到根节点,以区分左子树和右子树
    32         int inorder_root;
    33         for (inorder_root = in_start; inorder_root <= in_end; ++inorder_root)
    34         {
    35             if (inorder[inorder_root] == preorder[pre_start])
    36             {
    37                 break;
    38             }
    39         }
    40         //中序遍历中的左子树和右子树范围
    41         int inorder_left_start = in_start;
    42         int inorder_left_end = inorder_root - 1;
    43         int inorder_right_start = inorder_root + 1;
    44         int inorder_right_end = in_end;
    45         //前序遍历中的左子树和右子树范围
    46         int preorder_left_start = pre_start + 1;
    47         int preorder_left_end = preorder_left_start + (inorder_root - in_start) - 1;
    48         int preorder_right_start = preorder_left_end + 1;
    49         int preorder_right_end = pre_end;
    50 
    51         root->left = build(preorder, inorder, preorder_left_start, preorder_left_end, inorder_left_start, inorder_left_end);
    52         root->right = build(preorder, inorder, preorder_right_start, preorder_right_end, inorder_right_start, inorder_right_end);
    53 
    54         return root;
    55     }
    56 };
    View Code

    网上看了几篇文章,思路都是相似的,递归地构造出树。

  • 相关阅读:
    mysql 表映射为java bean 手动生成。
    MySQL 存储修改
    jdk 8 日期处理。
    jsp jstl quote symbol expected
    spring boot 接口用例测试
    spring boot js 文件引用 单引问题。
    spring boot 自定义视图路径
    spring 事务回滚。
    Eclipse svn 项目 星号
    Codeforces Round #277.5 (Div. 2)-B. BerSU Ball
  • 原文地址:https://www.cnblogs.com/laihaiteng/p/3802801.html
Copyright © 2011-2022 走看看