天天看点

1008. Construct Binary Search Tree from Preorder Traversal方法1: recursion方法2: recursion, O(n)方法3:iterative

1008. Construct Binary Search Tree from Preorder Traversal

  • 方法1: recursion
    • Complexity
    • 易错点:
  • 方法2: recursion, O(n)
    • Complexity
  • 方法3:iterative

Return the root node of a binary search tree that matches the given preorder traversal.

(Recall that a binary search tree is a binary tree where for every node, any descendant of node.left has a value < node.val, and any descendant of node.right has a value > node.val. Also recall that a preorder traversal displays the value of the node first, then traverses node.left, then traverses node.right.)

Example 1:

Input: [8,5,1,7,10,12]

Output: [8,5,10,1,7,null,12]

1008. Construct Binary Search Tree from Preorder Traversal方法1: recursion方法2: recursion, O(n)方法3:iterative

Note:

  1. 1 <= preorder.length <= 100
  2. The values of preorder are distinct.

方法1: recursion

思路:

递归建立子节点。每次在left == right 时建立一个新节点,否则在建立新节点后要向右方开始搜索,找到第一个大于当前节点的值,一定为root->right,而再右侧是右子树。因此可以递归对中间的范围调用递归,构建左子树, 剩下的范围构建右子树。

Complexity

Time complexity: O(n^2)

Space complexity: O(n)

易错点:

  1. 向右遍历查找要防止出界。
class Solution {
public:
    TreeNode* bstFromPreorder(vector<int>& preorder) {
        return bstHelper(preorder, 0, preorder.size() - 1);
    }
    
    TreeNode* bstHelper(vector<int> & preorder, int left, int right) {
        if (left > right || left < 0 || right >= preorder.size()) return nullptr;
        if (left == right) return new TreeNode(preorder[left]);
        
        TreeNode* root = new TreeNode(preorder[left]);
        int i = left + 1;
        while (i < preorder.size() && preorder[i] < preorder[left]) i++;
        root -> left = bstHelper(preorder, left + 1, i - 1);
        root -> right = bstHelper(preorder, i, right);
        return root;
    }
};
           

方法2: recursion, O(n)

思路:

根据修改上下界来判断下一个位置的数字是否能被放在当前数字的左子树或右子树,或者不能被放在本层。由于每个数字只遍历一次,复杂度是O(n)。

Complexity

Time complexity: O(n)

Space complexity: O(n)

class Solution {
private:
    int idx = 0;
public:
    TreeNode* bstFromPreorder(vector<int>& preorder) {
        return bstHelper(preorder, INT_MIN, INT_MAX);
    }
    
    TreeNode* bstHelper(vector<int> & preorder, int lower, int upper) {
        if (idx == preorder.size()) return nullptr;
        int val = preorder[idx];
        if (val < lower || val > upper) return nullptr;
        idx++;
        TreeNode* root = new TreeNode(val);
        root -> left = bstHelper(preorder, lower, val);
        root -> right = bstHelper(preorder, val, upper);
        return root;
    }
};
           

方法3:iterative

discussion: https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/discuss/252719/C%2B%2B-iterative-O(n)-solution-using-decreasing-stack

class Solution {
public:
    TreeNode* bstFromPreorder(vector<int>& preorder) {
        TreeNode dummy_root(INT_MAX);
        stack<TreeNode *> s;
        s.push(&dummy_root);
        for (int x : preorder) {
            auto n = new TreeNode(x);
            TreeNode *p = nullptr;
            while (s.top()->val < x) {
                p = s.top();
                s.pop();
            }
            if (p) {
                p->right = n;
            } else {
                s.top()->left = n;
            }
            s.push(n);
        }
        return dummy_root.left;
    }
};
           

继续阅读