Leetcode32. Longest Valid Parentheses

本文介绍了一种使用栈的数据结构解决寻找字符串中最长的有效括号子串长度的方法。通过遍历输入字符串,并利用栈记录未匹配的括号下标,最终计算出最长的有效括号子串的长度。

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

题目

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.

题目原意是给定一个只含‘(’和')'的串,要我们给出串中最长的所有括号都匹配的子串的长度

题目分析

首先要先明确哪个括号是和哪个括号匹配的,如果括号匹配类型的题目做得多的话我们知道遇上括号匹配的问题通常都是建立一个栈,然后把括号放入,当要放入‘)’遇上栈顶的‘(’的时候就表示出现了一个括号匹配并把栈顶的‘(’弹出,也就是说,‘)’永远是和离它最近的没和其他‘)’匹配的‘(’匹配的。对于这道题,要得到一个所有括号都匹配的子串也就是子串里的括号都得到了匹配,而子串两端的两个括号都是没有匹配的,也就是说,即使子串右端是‘(’,这个也是没有匹配的,否则他也归入这个子串了,这也代表没有匹配的括号中间是子串。如果这样想的话,那么这题就很简单了,我们只要先对总串中的每一个括号都判断他是否匹配的,对于不能匹配的括号存下他们的下标,在这些括号中间的就是能符合条件的子串,只要从中找出最长的即可。
想到括号匹配自然用栈来完成,只不过这里的栈存的是括号的下标,从串的开头扫一遍串,每遇到一个括号就进行如下操作:
如果栈原来为空就把这个括号的下标放入栈看下一个括号,如果不空,那么有两种情况:
1.遇到的是‘(’,那么这种就把下标放入栈去看下一个括号
2.遇到的是‘)’,那么这种看栈顶下标对应的元素是不是‘(’,如果是的话则把栈顶元素弹出去看下一个括号,如果不是则把这个括号放入(这个括号不会再有机会弹出栈,表示他是个没有匹配的括号)
当总串扫描完后,我们只要把栈顶元素逐个pop出来,相邻两个元素的差值就是子串的长度,记录下其中最长的即可

c++代码

class Solution {
public:
    int longestValidParentheses(string s) {
        stack<int> invalid_index;
        for (int i = 0; i < s.length(); i++) {
            if (invalid_index.size() == 0) {
                invalid_index.push(i);
                continue;
            }
            else {
                if (s[invalid_index.top()] == '(') {
                    if (s[i] == ')') invalid_index.pop();
                    else invalid_index.push(i);
                }
                else {
                    invalid_index.push(i);
                }
            }
        }
        int max = 0, temp = s.length();
        while(!invalid_index.empty()) {
            int t = invalid_index.top();
            invalid_index.pop();
            if (max < temp - t - 1) max = temp - t - 1;
            temp = t;
        }
        if (max < temp) max = temp;
        return max;
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值