LeetCode 255. Verify Preorder Sequence in Binary Search Tree

方法一:Divide and Conquer

数组第一个一定是根,第一个大于根的一定是右子树的根,因此我们可以把 根,左右子树都区分开来。判断根是否在合理范围内,如果在,在分别判断左右子树。思路清晰,也很容易写。

Time: O(nlogn)

class Solution {
public:
    bool verifyPreorder(vector<int>& preorder) {
        return helper(preorder,0,preorder.size()-1,INT_MIN,INT_MAX);
    }
    
    bool helper(vector<int> &preorder, int start, int end, int lower, int upper){ //[start,end]
        if (start>end) return true;
        int root_val=preorder[start];
        if (!(root_val>lower && root_val<upper)) return false;
        int i;
        for (i=start+1;i<=end;++i){
            if (preorder[i]>root_val) break;
        }
        // [start+1,i-1] and [i,end]
        return helper(preorder,start+1,i-1,lower,root_val) && helper(preorder,i,end,root_val,upper);
    }
};

方法二:Stack

维护一个单调递减的栈。如果当前元素比栈顶元素小,说明是左子树,压栈;否则是右子树,此时 lower_bound 要更新,因为后面的元素一定比出栈元素大了。

下面这张图可以帮助理解。时间复杂度和空间复杂度都为O(n)

class Solution {
public:
    bool verifyPreorder(vector<int>& preorder) {
        int lower=INT_MIN;
        stack<int> s;
        for (int x:preorder){
            if (x<=lower) return false;
            while (!s.empty() && x>s.top()){
                lower = s.top();
                s.pop();
            }
            s.push(x);
        }
        return true;
    }
};

猜你喜欢

转载自www.cnblogs.com/hankunyan/p/9563580.html