LeetCode 每日一题 105. 从前序与中序遍历序列构造二叉树

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

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

例如,给出

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

返回如下的二叉树:

  3
  / \
9  20
  /  \
  15   7

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


DFS(pos_in_preorder,pos_in_inorder,sizeof_tree) 三个参数分别是树在先序、中序的开始位置和树的大小。

当然,使用常见的 (left,right) 来表示树的位置亦可,看哪种让自己的思路更加清晰。例如,二分的时候使用 while(len > 0) 让我少了很对对死循环的担心[捂脸]

一些优化:使用 map<int,int> 记录值在中序的位置;用 unordered_map<int,int>map<int,int> 测试结果更优。

/**
 * 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 {
 private:

  TreeNode* DFS(vector<int>&preo,vector<int>&ino,unordered_map<int, int>&pos_in_inorder,int pp, int ip, const int n){
    if(n == 0)
      return NULL;

    TreeNode * root = new TreeNode(preo[pp]);
    int i = pos_in_inorder[preo[pp]] - ip;
    if(ino[ip + i] == preo[pp]) {
      root->left = DFS(preo,ino,pos_in_inorder,pp + 1, ip, i);
      root->right = DFS(preo,ino,pos_in_inorder,pp + i + 1, ip + i + 1, n - i - 1);
      return root;
    }
    return NULL;
  }

 public:
  TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    if(preorder.size() == 0 )
      return NULL;
    unordered_map<int, int>pos_in_inorder;
    for(int i = 0; i < inorder.size(); ++i)
      pos_in_inorder[inorder[i]] = i;
    return DFS(preorder,inorder,pos_in_inorder,0, 0, preorder.size());
  }
};
posted @ 2020-05-22 09:37  菁芜  阅读(123)  评论(0编辑  收藏  举报