LeetCode刷题笔记 105. 从前序与中序遍历序列构造二叉树

105. 从前序与中序遍历序列构造二叉树

  • 题目要求
  • 语法学习
    • next
  • 递归
    • playgroud追踪
      • 输出
  • 迭代
    • playgroud追踪
    • 输出

题目要求

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

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

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

语法学习

next

next

next(x) 相当于 next(1)
next(x,n) 相当于以x为数组0元素位置的x(n)

递归

思路图解

https://github.com/soulmachine/leetcode

class Solution {
public:
    template<typename T>
    TreeNode* buildTree(T prefirst,T prelast,T infirst,T inlast){
        if(prefirst==prelast) return nullptr;
        if(infirst==inlast) return nullptr;

        auto root=new TreeNode(*prefirst);
        auto inRootPos=find(infirst,inlast,*prefirst);
        auto leftSize=distance(infirst,inRootPos);
        // 第leftSize个元素并不在左子树中,而包含在右子树中
        root->left=buildTree(next(prefirst),next(prefirst,leftSize+1),
                infirst,inRootPos);
        root->right=buildTree(next(prefirst,leftSize+1),prelast,next(inRootPos),inlast);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return buildTree(begin(preorder),end(preorder),begin(inorder),end(inorder));
    }    
};

playgroud追踪

class Solution {
public:
    template<typename T>
    TreeNode* buildTree(T prefirst,T prelast,T infirst,T inlast){
        cout<<"prefirst : " << *prefirst <<endl;
        cout<<"prelast : " << *prelast <<endl;
        cout<<"infirst : "<< *infirst <<endl;
        cout<<"inlast : " << *inlast <<endl;
        if(prefirst==prelast) return nullptr;
        if(infirst==inlast) return nullptr;
        

        auto root=new TreeNode(*prefirst);
        auto inRootPos=find(infirst,inlast,*prefirst);
        auto leftSize=distance(infirst,inRootPos);
        cout<<"leftSize : " << leftSize <<endl;
        cout<<"-------------------------------------------------"<<endl;
        root->left=buildTree(next(prefirst),next(prefirst,leftSize+1),infirst,next(infirst,leftSize));
        root->right=buildTree(next(prefirst,leftSize+1),prelast,next(inRootPos),inlast);
        return root;
    }
执行用时 内存消耗
12 ms 25.8 MB

输出

prefirst : 3
prelast : -1094795586
infirst : 9
inlast : -1094795586
leftSize : 1
-------------------------------------------------
prefirst : 9
prelast : 20
infirst : 9
inlast : 3
leftSize : 0
-------------------------------------------------
prefirst : 20
prelast : 20
infirst : 9
inlast : 9
prefirst : 20
prelast : 20
infirst : 3
inlast : 3
prefirst : 20
prelast : -1094795586
infirst : 15
inlast : -1094795586
leftSize : 1
-------------------------------------------------
prefirst : 15
prelast : 7
infirst : 15
inlast : 20
leftSize : 0
-------------------------------------------------
prefirst : 7
prelast : 7
infirst : 15
inlast : 15
prefirst : 7
prelast : 7
infirst : 20
inlast : 20
prefirst : 7
prelast : -1094795586
infirst : 7
inlast : -1094795586
leftSize : 0
-------------------------------------------------
prefirst : -1094795586
prelast : -1094795586
infirst : 7
inlast : 7
prefirst : -1094795586
prelast : -1094795586
infirst : -1094795586
inlast : -1094795586
[3, 9, 20, null, null, 15, 7, null, null, null, null]

迭代

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0) return nullptr;
        TreeNode *root=new TreeNode(preorder[0]);
        int length=preorder.size();
        stack<TreeNode*> s;
        s.push(root);
        int inorderIndex=0;
        for(int i=1;i<length;i++){
            int preorderVal=preorder[i];
            TreeNode *Node=s.top();
            if(Node->val!=inorder[inorderIndex]){
                Node->left=new TreeNode(preorderVal);
                s.push(Node->left);                
            }
            else{
                while(!s.empty()&&s.top()->val==inorder[inorderIndex]){
                    Node=s.top();
                    s.pop();
                    inorderIndex++;
                }
                Node->right=new TreeNode(preorderVal);
                s.push(Node->right);
            }
        }
        return root;
    }
};
执行用时 内存消耗
12 ms 19.1 MB

playgroud追踪

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.size()==0) return nullptr;
        TreeNode *root=new TreeNode(preorder[0]);
        int length=preorder.size();
        stack<TreeNode*> s;
        s.push(root);
        int inorderIndex=0;
        for(int i=1;i<length;i++){
            cout<<"i= "<<i<<endl;
            int preorderVal=preorder[i];
            cout<<"preorderVal= "<<preorderVal<<endl;
            TreeNode *Node=s.top();
            cout<<"Node= "<<Node->val<<endl;
            cout<<"inorderIndex= "<<inorderIndex<<endl;
            cout<<"inorder[inorderIndex]= "<<inorder[inorderIndex]<<endl;
            if(Node->val!=inorder[inorderIndex]){
                Node->left=new TreeNode(preorderVal);
                s.push(Node->left);                
            }
            else{
                while(!s.empty()&&s.top()->val==inorder[inorderIndex]){
                    Node=s.top();
                    s.pop();
                    inorderIndex++;
                    cout<<"@ inorderIndex= "<<inorderIndex<<endl;
                }
                Node->right=new TreeNode(preorderVal);
                s.push(Node->right);
            }
        }
        return root;
    }
};

输出

stdin
[3,9,8,5,4,10,20,15,7]
[4,5,8,10,9,3,15,20,7]
        3
       / \
      9  20
     /  /  \
    8  15   7
   / \
  5  10
 /
4
i= 1
preorderVal= 9
Node= 3
inorderIndex= 0
inorder[inorderIndex]= 4
i= 2
preorderVal= 8
Node= 9
inorderIndex= 0
inorder[inorderIndex]= 4
i= 3
preorderVal= 5
Node= 8
inorderIndex= 0
inorder[inorderIndex]= 4
i= 4
preorderVal= 4
Node= 5
inorderIndex= 0
inorder[inorderIndex]= 4
i= 5
preorderVal= 10
Node= 4
inorderIndex= 0
inorder[inorderIndex]= 4
@ inorderIndex= 1
@ inorderIndex= 2
@ inorderIndex= 3
i= 6
preorderVal= 20
Node= 10
inorderIndex= 3
inorder[inorderIndex]= 10
@ inorderIndex= 4
@ inorderIndex= 5
@ inorderIndex= 6
i= 7
preorderVal= 15
Node= 20
inorderIndex= 6
inorder[inorderIndex]= 15
i= 8
preorderVal= 7
Node= 15
inorderIndex= 6
inorder[inorderIndex]= 15
@ inorderIndex= 7
@ inorderIndex= 8
[3, 9, 20, 8, null, 15, 7, 5, 10, null, null, null, null, 4, null, null, null, null, null]

你可能感兴趣的:(LeetCode刷题笔记 105. 从前序与中序遍历序列构造二叉树)