Ruby's Louvre

每天学习一点点算法

导航

leetcode 32. Longest Valid Parentheses

难题

var longestValidParentheses = function(s) {
    if (s == null || s.length < 1) return 0;

        var maxans = 0;
        var stack = []
        stack.push(-1);
        for (var i = 0; i < s.length; i++) {
            if (s.charAt(i) == '(') {
                stack.push(i);
            } else {
                stack.pop();
                if (!stack.length) stack.push(i);
                else maxans = Math.max(maxans, i - stack[stack.length-1]);
            }
        }
        return maxans;

};

此题还有一种不用额外空间的解法,使用了两个变量 left 和 right,分别用来记录到当前位置时左括号和右括号的出现次数,当遇到左括号时,left 自增1,右括号时 right 自增1。对于最长有效的括号的子串,一定是左括号等于右括号的情况,此时就可以更新结果 res 了,一旦右括号数量超过左括号数量了,说明当前位置不能组成合法括号子串,left 和 right 重置为0。但是对于这种情况 "(()" 时,在遍历结束时左右子括号数都不相等,此时没法更新结果 res,但其实正确答案是2,怎么处理这种情况呢?答案是再反向遍历一遍,采取类似的机制,稍有不同的是此时若 left 大于 right 了,则重置0,这样就可以 cover 所有的情况了,参见代码如下:

var longestValidParentheses = function(s) {
    if (s == null || s.length < 1) return 0;

       var res = 0, left = 0, right = 0, n = s.length;
        for (var i = 0; i < n; ++i) {
            (s[i] == '(') ? ++left : ++right;
            if (left == right) res = Math.max(res, 2 * right);
            else if (right > left) left = right = 0;
        }
        left = right = 0;
        for (var i = n - 1; i >= 0; --i) {
            (s[i] == '(') ? ++left : ++right;
            if (left == right) res = Math.max(res, 2 * left);
            else if (left > right) left = right = 0;
        }
        return res;
};

posted on 2019-12-15 13:48  司徒正美  阅读(202)  评论(0编辑  收藏  举报