1. 程式人生 > 其它 >1008. 前序遍歷構造二叉搜尋樹

1008. 前序遍歷構造二叉搜尋樹

返回與給定前序遍歷preorder 相匹配的二叉搜尋樹(binary search tree)的根結點。

(回想一下,二叉搜尋樹是二叉樹的一種,其每個節點都滿足以下規則,對於node.left的任何後代,值總 < node.val,而 node.right 的任何後代,值總 > node.val。此外,前序遍歷首先顯示節點node 的值,然後遍歷 node.left,接著遍歷 node.right。)

題目保證,對於給定的測試用例,總能找到滿足要求的二叉搜尋樹。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal


著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

藉助單調棧

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

class Solution {

    private Map<Integer, Integer> rightGreaterIndexMap;

    private TreeNode solve(int[] preorder, int start, int end) {
        if (start > end) {
            return null;
        }
        TreeNode root = new TreeNode(preorder[start]);

        Integer rightPos = rightGreaterIndexMap.get(start);

        if (rightPos == null) {
            root.left = solve(preorder, start + 1, end);
            root.right = null;
        } else {
            root.left = solve(preorder, start + 1, rightPos - 1);
            root.right = solve(preorder, rightPos, end);
        }
        return root;
    }

    public TreeNode bstFromPreorder(int[] preorder) {
        rightGreaterIndexMap = new HashMap<>();
        Stack<Integer> stack = new Stack<>();
        for (int i = preorder.length - 1; i >= 0; --i) {
            while (!stack.isEmpty() && preorder[stack.peek()] < preorder[i]) {
                stack.pop();
            }
            if (!stack.isEmpty()) {
                rightGreaterIndexMap.put(i, stack.peek());
            }
            stack.push(i);
        }
        return solve(preorder, 0, preorder.length - 1);
    }
}


class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

上界與下界

public class Solution {

    private int index = 0;
    private int[] preorder;
    private int len;

    /**
     * 深度優先遍歷,遍歷的時候把左右邊界的值傳下去
     *
     * @param preorder
     * @return
     */
    public TreeNode bstFromPreorder(int[] preorder) {
        this.preorder = preorder;
        this.len = preorder.length;
        return dfs(Integer.MIN_VALUE, Integer.MAX_VALUE);
    }

    /**
     * 通過下限和上限來控制指標移動的範圍
     *
     * @param lowerBound
     * @param upperBound
     * @return
     */
    private TreeNode dfs(int lowerBound, int upperBound) {
        // 所有的元素都已經新增到了二叉樹中
        if (index == len) {
            return null;
        }

        int cur = preorder[index];
        if (cur < lowerBound || cur > upperBound) {
            return null;
        }

        index++;
        TreeNode root = new TreeNode(cur);
        root.left = dfs(lowerBound, cur);
        root.right = dfs(cur, upperBound);
        return root;
    }
}
心之所向,素履以往 生如逆旅,一葦以航