c语言最长有效括号,[Leetcode] Longest Valid Parentheses 最长有效括号对

本文介绍了两种方法解决找到给定字符串中最长有效括号子串的问题。第一种方法是使用栈,通过维护括号的匹配情况计算最长长度;第二种方法是采用动态规划,从前向后逐步计算最长括号对。每种方法的时间复杂度均为O(N),空间复杂度也为O(N)。文章还提供了后续问题,探讨了如何在不使用额外空间的情况下求解,并给出了相应的思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Longest Valid Parentheses

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.

栈法 Stack

复杂度

时间 O(N) 空间 O(N)

思路

用Stack的方法本质上和Valid Parentheses是一样的,一个右括号能消去Stack顶上的一个左括号。不同的是,为了能够计算括号对的长度我们还需要记录括号们的下标。这样在弹出一个左括号后,我们可以根据当前坐标减去栈中上一个(也就是Pop过后的Top元素)的坐标来得到该有效括号对的长度。

代码

public class Solution {

public int longestValidParentheses(String s) {

Stack stk = new Stack();

int maxLen = 0;

for(int i = 0; i < s.length(); i++){

//遇到左括号,将其push进栈

if(s.charAt(i)=='('){

stk.push(new Parenthese(i, '('));

} else {

//遇到右括号,分类讨论

//如果当前栈顶是左括号,则消去并计算长度

if(!stk.isEmpty() && stk.peek().symb=='('){

int curLen = 0;

stk.pop();

if(stk.isEmpty()){

curLen = i + 1;

} else {

curLen = i - stk.peek().indx;

}

maxLen = Math.max(maxLen, curLen);

} else {

//如果栈顶是右括号或者是空栈,则将右括号也push进栈,它的坐标将方便之后计算长度

stk.push(new Parenthese(i, ')'));

}

}

}

return maxLen;

}

public class Parenthese {

int indx;

char symb;

public Parenthese (int i, char s){

this.indx = i;

this.symb = s;

}

}

}

动态规划法 Dynamic Programming

复杂度

时间 O(N) 空间 O(N)

思路

动态规划法将大问题化为小问题,我们不一定要一下子计算出整个字符串中最长括号对,我们可以先从后向前,一点一点计算。假设d[i]是从下标i开始到字符串结尾最长括号对长度,s[i]是字符串下标为i的括号。如果s[i-1]是左括号,如果i + d[i] + 1是右括号的话,那d[i-1] = d[i] + 1。如果不是则为0。如果s[i-1]是右括号,因为不可能有右括号开头的括号对,所以d[i-1] = 0。

代码

public class Solution {

public int longestValidParentheses(String s) {

int[] dp = new int[s.length()];

int maxLen = 0;

for(int i = s.length()-2; i >=0; i--){

if(s.charAt(i)=='('){

int end = i + dp[i+1] + 1;

if(end < s.length() && s.charAt(end)==')'){

dp[i] = dp[i+1] + 2;

if(end + 1 < s.length()){

dp[i] += dp[end + 1];

}

}

}

maxLen = Math.max(maxLen, dp[i]);

}

return maxLen;

}

}

后续 Follow Up

Q:能否不用额外空间求解?

A:可以,但是要提高时间复杂度。比如((()()),先遍历一遍将所有的()替换成00,得到((0000),再遍历一遍,替换所有的(00...00)这种形式字符串为000...000,这里我们得到(000000,直到遍历完无法替换更多括号为之。如果所有符号都是0,说明是有效的。这样的时间复杂度是O(N)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值