經過前序和中序遍歷構造二叉樹

原題

  Given preorder and inorder traversal of a tree, construct the binary tree.
  Note:
  You may assume that duplicates do not exist in the tree.node

題目大意

  給定一個前序和中序遍歷序列,構建一個二叉樹
  注意:
   - 二叉樹中元素重複元素算法

解題思路

  前序遍歷第一個元素是根結點(k),在中序遍歷序列中找值爲k的下標idx,idx將中序遍歷序列分紅左右子樹,對前序遍歷序列也同樣,可進行遞歸操做ui

代碼實現

樹結點類spa

public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

 

算法實現類一:.net

public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder == null || preorder.length ==0){
            return null;
        }
        HashMap<Integer, Integer> inorderMap = new HashMap<Integer, Integer>();
        for (int i=0;i<inorder.length;i++){
            inorderMap.put(inorder[i],i);
        }

        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        TreeNode root = new TreeNode(preorder[0]);
        stack.push(root);
        for (int i=1;i<preorder.length;i++){
            TreeNode top = stack.peek();
            int indexTop = inorderMap.get(top.val);
            int indexVal = inorderMap.get(preorder[i]);

            TreeNode node = new TreeNode(preorder[i]);

            if (indexVal<indexTop){
                top.left=node;
            }
            else{
            while (indexVal>indexTop){
                    top = stack.pop();
                    indexTop = stack.isEmpty()?Integer.MAX_VALUE:inorderMap.get(stack.peek().val);
                }
                top.right = node;
            }
            stack.push(node);
        }
        return root;
    }
}

 

算法實現類二:(會超時)code

public class Solution {

    public TreeNode buildTree(int[] preorder, int[] inorder) {

        // 參數校驗
        if (preorder == null || inorder == null || preorder.length == 0
                || preorder.length != inorder.length) {
            return null;
        }
        return solve(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
    }

    /**
     * 構建二叉樹,數據輸入的正確性由輸入數據本身保證
     *
     * @param preorder 先序遍歷的結果
     * @param x        先序遍歷的開始位置
     * @param y        先序遍歷的結束位置
     * @param inorder  中序遍歷的結果
     * @param i        中序遍歷的開始位置
     * @param j        中序遍歷的結束位置
     * @return 二叉樹的根結點
     */
    public TreeNode solve(int[] preorder, int x, int y, int[] inorder, int i, int j) {

        if (x >= 0 && x <= y && i >= 0 && i <= j) {
            // 只有一個元素
            if (x == y) {
                return new TreeNode(preorder[x]);
            } else if (x < y) {
                // 記錄根結點的索引
                int idx = i;
                while (idx <= j && inorder[idx] != preorder[x]) {
                    idx++;
                }

                // 建立根結點
                TreeNode root = new TreeNode(inorder[idx]);

                // 左子樹的結點個數
                int leftLength = idx - i;
                //
                if (leftLength > 0) {
                    // x + 1, x + leftLength:左子樹起始和結束位置
                    root.left = solve(preorder, x + 1, x + leftLength, inorder, i, idx - 1);
                }

                // 右子樹的結點個數
                int rightLength = j - idx;
                if (rightLength > 0) {
                    // x + leftLength + 1, y:右子樹起始和結束位置
                    root.right = solve(preorder, x + leftLength + 1, y, inorder, idx + 1, j);
                }
                return root;
            }
        }

        return null;
    }
}
相關文章
相關標籤/搜索