1. 程式人生 > 其它 >正則表示式--grep

正則表示式--grep

從前序與中序遍歷序列構造二叉樹
給定一棵樹的前序遍歷 preorder 與中序遍歷 inorder。請構造二叉樹並返回其根節點
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
作者:力扣 (LeetCode)
連結:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvix0d/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
答案參考了評論區大佬。

首先,需要明白,前序遍歷二叉樹的順序。其第一個結點必然是根節點,然後若根節點有左子樹,其根節點的下一個節點必然為其左子樹的根節點。否則,若有右子樹,則下一個節點必然為右子樹的根節點。(前序是從前往後看,後序從後往前看就可以)
明確這個邏輯就好辦了,那麼我們如何知道根節點有無左右子樹呢?這就需要通過中序遍歷順序來確定了。在中序順序中,根節點左側為其左子樹,右側為其右子樹。我們只想要知道有沒有左右子樹即可,所以只需確定中序順序中根節點的左右兩側的元素個數即可。

1.遞迴

1.每輪遞迴返回當前前序序列的根節點,返回後在前序序列中刪掉根節點。
2.由中序序列遞迴其左右子樹。
3.遞迴返回結果連線到當前根節點的左右孩子上。

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0){
            return null;
        }
        List<Integer> pre = new ArrayList<>();
        List<Integer> in = new ArrayList<>();
        for(int i = 0; i < preorder.length; i++){
            pre.add(preorder[i]);
            in.add(inorder[i]);
        }
        return recursion(pre, in);    
    }
    public TreeNode recursion(List<Integer> pre, List<Integer> in){
        if(in.size() == 0){
            return null;
        }
        int midVal = pre.remove(0);
        TreeNode root = new TreeNode(midVal);
        int mid = in.indexOf(midVal);
        root.left = recursion(pre, in.subList(0, mid));
        root.right = recursion(pre, in.subList(mid + 1, in.size()));
        return root;
    }

2.非遞迴

擷取主集合的操作都可以轉換成由雙指標指示陣列範圍。唯一需要注意的就是由於不能在陣列中刪除元素。所以當前的根節點的左右子樹根節點位置需要想辦法獲取,如果是左子樹根,那麼就下一位就是,如果是右子樹根那麼就需要跨過中間的所有左子樹的結點。也就是中序序列中的:根位置-當前樹起始位置+1

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if(preorder.length == 0){
            return null;
        }
        return recursion(preorder, inorder, 0, 0, inorder.length - 1);    
    }
    public TreeNode recursion(int[] preorder, int[] inorder, int preCur, int inBegin, int inEnd){
        if(preCur > preorder.length - 1 || inBegin > inEnd){
            return null;
        }
        int midVal = preorder[preCur];
        TreeNode root = new TreeNode(midVal);
        int mid = -1;
        for(int i = 0; i < inorder.length; i++){
            if(inorder[i] == midVal){
                mid = i;
                break;
            }
        }
        root.left = recursion(preorder, inorder, preCur + 1, inBegin, mid - 1);
        root.right = recursion(preorder, inorder, preCur + mid - inBegin + 1, mid + 1, inEnd);
        return root;
    }