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;
    }
}
posted @ 2021-12-22 22:17  Tianyiya  阅读(131)  评论(0)    收藏  举报