【LeetCode 105】從前序與中序遍歷序列構造二叉樹

思路:觀察發現,首先從preorder獲得根結點,從inorder找到根結點所在位置index,inorder[i]之前的內容爲左子樹,之後的內容爲右子樹。

left和right記錄的是preorder的邊界,start和end記錄的是inorder的邊界

 public TreeNode buildTree(int[] preorder, int[] inorder) {
        TreeNode root=buildTreeCore(preorder, 0, preorder.length, inorder, 0, inorder.length);
        return root;
    }

    public TreeNode buildTreeCore(int[] preorder, int left, int right, int[] inorder, int start, int end) {
        if(left>right||start>end||left>=preorder.length||start>=inorder.length) return null;
        if(start==end) return new TreeNode(inorder[start]);

        TreeNode root=new TreeNode(preorder[left]);

        //採用循環尋找根結點在inorder中的位置
        for(int i=start;i<end;i++){
            if(inorder[i]==preorder[left]){
                //計算左子樹結點數量
                int leftSize=i-start;
                if(leftSize!=0){
                    //遞歸重構左子樹
                    root.left=buildTreeCore(preorder, left+1, left+leftSize, inorder, start, i);
                }

                //遞歸重構右子樹
                int rightRoot=left+leftSize+1;
                root.right=buildTreeCore(preorder, rightRoot, right, inorder, i+1, end);
                break;
            }
        }

        return root;
    }

優化:因爲樹結點不會重複,所以可以將inorder結點與下標使用hashmap儲存起來,可以提升效率。

public TreeNode buildTree(int[] preorder, int[] inorder) {
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<inorder.length;i++){
            map.put(inorder[i],i);
        }
        
        TreeNode root=buildTreeCore(preorder, 0, preorder.length, inorder, 0, inorder.length, map);
        return root;
    }

    public TreeNode buildTreeCore(int[] preorder, int left, int right, int[] inorder, int start, int end, HashMap<Integer,Integer> map) {
        if(left>right||start>end||left>=preorder.length||start>=inorder.length) return null;
        if(start==end) return new TreeNode(inorder[start]);

        TreeNode root=new TreeNode(preorder[left]);
        
        //直接獲取下標,省去循環的時間消耗
        int index=map.get(preorder[left]);
        int leftSize=index-start;
        if(leftSize!=0){
            root.left=buildTreeCore(preorder, left+1, left+leftSize, inorder, start, index, map);
        }

        int rightRoot=left+leftSize+1;
        root.right=buildTreeCore(preorder, rightRoot, right, inorder, index+1, end, map);

        return root;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章