【算法】【Dynamic Programming】Longest Valid Parentheses

Difficulty: Hard

Description

Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.

For “(()”, the longest valid parentheses substring is “()”, which has length = 2.

Another example is “)()())”, where the longest valid parentheses substring is “()()”, which has length = 4.

Solution

思路

自己的实现

  1. 找到(开头的字符,一直往下扫描;
  2. (的数量多于或等于)的数量,继续扫描(字符串直到目前合法);
  3. (的数量少于)的数量,说明不合法,记录之前合法字符串最大长度,回到第1步。

自己的实现有个缺点:扫描到末尾,要从末尾往回再扫描一部分,因为要处理类似(()的情况。

class Solution {
public:
    int longestValidParentheses(string s) {
        int len = s.length();
        int i = 0, j = -1, max = 0, left = 1, right = 0;
        for (; i < len && j < len;) {
            i = j + 1;
            // 找到'('开头
            for (; i < len && s[i] == ')'; ++i) {}
            if (i < len) {
                for (j = i + 1; j < len; ++j) {
                    if (s[j] == '(') ++left;
                    else ++right;
                    if (left < right) {
                        max = (max < j - i) ? j - i : max;
                        left = 1;
                        right = 0;
                        break;
                    }
                }
            }
        }
        // 处理最后的一串括号
        --j;
        while (j > i) {
            for (; j > i && s[j] == '('; --j) {}
            if (j > i) {
                for (right = 0, left = 0; j >= i; --j) {
                    if (s[j] == ')') right++;
                    else left++;
                    if (left > right) break;
                }
            }
            max = (max < 2 * right) ? 2 * right : max;
        }


        return max;
    }
};

更好的实现

使用栈,把字符所属的下标一个一个压入栈,若先后压入的下标分别代表(),则弹出这两个下标,目前下标减去栈顶的下标,则是目前的maxLength

class Solution {
public:
    int longestValidParentheses(string s) {
        stack<int>stackk;

        int maxLength = 0;
        //(()

        stackk.push(-1);

        for (int i = 0; i < s.size(); ++i) {
            int t = stackk.top();

            if (t != -1 && s[i] == ')' && s[t] == '(') {
                stackk.pop();
                maxLength = max(maxLength, i - stackk.top());
            }
            else {
                stackk.push(i);
            }
        }

        return maxLength;
    }

    int max(int a, int b) {
        if (a < b) return b;
        return a;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值