首页
学习
活动
专区
圈层
工具
发布

Leetcode之Longest Valid Parentheses

好久没来更新Leetcode题目了,因为之前都去刷lintcode了,结果发现还是leetcode是我的本命啊~~

第二次刷leetcode,感触良多,有些题目以前不会现在会了,但是有些以前明明会的,现在反而想很久,还有可能需要看提示,而且复杂度还比以前的高了,感觉人变笨了

,肯定因为很久没来更新博客的原因。嗯,所以今天就讲一讲Longest Valid Parentheses这道题吧。

今天重新做这道题时,一开始想得太简单了,没考虑需要连续的子串,导致一开始的O(n)做法出错了,然后偷瞄了一下提示,动规,好吧,一开始也有想过,但是没细想进去,重新想了一下,确实可以做,递推公式如下:

代码如下:

代码语言:javascript
复制
int longestValidParentheses(string s) {
        int len = s.length();
        vector<int> dp(len + 1, 0);
        for (int i = 0; i < len; i++) {
            int count = 0;
            for (int k = i; k >= 0; k--) {
                if (s[k] == ')') {
                    count++;
                } else {
                    count--;
                    if (count == 0) {
                        dp[i + 1] = max(dp[i + 1], dp[k] + i - k + 1);
                    } else if (count < 0) {
                        break;
                    }
                }
            }
            if (i - dp[i] - 1 >= 0 && s[i - dp[i] - 1] == '(' && s[i] == ')') 
                dp[i + 1] = max(dp[i] + 2, dp[i + 1]);
        }
        return *max_element(dp.begin(), dp.end());
    }

另一种做法是,用一个栈保存已经遍历过的左括号,然后求出所有左括号是否都有匹配,最后遍历左括号数组,将连续的左括号的长度相加,遇到0就重新算,得到最长长度。这样的复杂度确实就是O(n),佩服以前的我。

代码语言:javascript
复制
class Solution {
public:
struct Letter{
	char val;
	int index;
	Letter(char v,int i):val(v),index(i){};
};
int longestValidParentheses(string s) {
	int result=0,max=0;
	stack<Letter> letterStack;
	vector<int> letterCount;
	for(int i=0;i<s.length();i++){
		if(s[i]==')'&&letterStack.size()==0){
			letterCount.push_back(0);
			continue;
		}else if(s[i]=='('){
			letterStack.push(Letter(s[i],letterCount.size()));
			letterCount.push_back(0);
		}else{
			Letter topLetter=letterStack.top();
			letterCount[topLetter.index]+=2;
			letterStack.pop();
		}
	}
	for(int i=0;i<letterCount.size();i++){
		if(letterCount[i]==0){
			if(max>result){
				result=max;
			}
			max=0;
		}else{
			max+=letterCount[i];
		}
	}
	if(max>result)
		result=max;
	return result;
}
};
下一篇
举报
领券