leetcode 20|22|32. Valid Parentheses 22. Generate Parentheses 32. Longest Valid Parentheses

本文探讨了三种涉及括号的算法问题:括号的有效性验证、括号组合生成及最长有效括号子串的寻找。通过栈结构实现括号匹配,确保括号序列的有效性和正确性。

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

20. Valid Parentheses

Given a string containing just the characters '('')''{''}''[' and ']', determine if the input string is valid.

The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.

想到用栈

class Solution {
public:
    bool isValid(string s) 
    {
        if (s.size() == 0)
            return true;
        
        stack<char> pp;
        int i = 0;
        while (i < s.size())
        {
            if (!pp.empty())
            {
                char k = pp.top();
                if((s[i] == ']' && k == '[') || (s[i] == '}' && k == '{') || (s[i] == ')' && k == '('))
                    pp.pop();
                else
                    pp.push(s[i]);
            } 
            else if (s[i] == ']' || s[i] == ')' || s[i] == '}')
                return false;
            else 
                pp.push(s[i]);           
            i++;
        }
        return pp.empty();
    }
};

22. Generate Parentheses

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

left代表还有几个( 需要插入
right 同理

class Solution {
public:
    void genera(vector<string> &str, string &ss, int left, int right)
    {   
        if (left == 0 && right == 0)
        {
            str.push_back(ss);
            return;
        }
        
        string pp;
        if (left == right && left != 0)
        {
            pp = ss + '(';
            genera(str, pp, left - 1, right);
        }
        else if (left < right && left > 0)
        {
            pp = ss + '(';
            genera(str, pp, left - 1, right);
            pp = ss + ')';
            genera(str, pp, left, right - 1);
        }
        else if(left == 0 && right != 0)
        {
            pp = ss + ')';
            genera(str, pp, left, right - 1);
        }
    }
    
    vector<string> generateParenthesis(int n)
    {
        vector<string> str;
        string ss = "";
        genera(str, ss, n, n);
        return str;
    }
};

32. 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.

首先,想到用栈并不太难。最难的是想到往栈里面存储什么,借助20题的思路,最直白的想法是存储左括号'(',但是这样做的话,没法解决上面的问题。所以在栈里存储左括号'('的下标index。这样才能正确地计算可能的最长距离。
      其次,把问题简化一下,先不找最长的括号串,先找候选括号串。什么是候选括号串呢?需要满足的第一个条件是'('和')'的数量相等(所以,上面提到了使用了栈来进行左右括号是否匹配的检查),需要满足的第二个条件是,匹配的过程中不能出现')('的情况。也就是说,某个时刻,发现有单独的')'出现了,就说明此时此刻的候选串结束了,将开始对新的候选串的检查了。

class Solution {
public:
    int longestValidParentheses(string s)
    {
        stack<int> paranStack;  
        int maxLength = 0;  
        int lastValidIndx = 0;  
        for (int indx = 0; indx < s.length(); indx++) 
        {  
            if (s[indx] == '(') //遇到左括号,直接存入。  
                paranStack.push(indx);  
            else //遇到右括号,分情况讨论  
            { 
                //如果此时栈里左括号已经被消耗完了,没有额外的左括号用来配对当前的右括号了,那么当前的右括号就被单出来了,表明当前子串可以结束了,此时的右括号也成为了下一个group的分界点,此时右括号下标为index,所以下一个group的起始点为index+1,相当于skip掉当前的右括号。
                if (paranStack.empty())   
                    lastValidIndx = indx + 1;  
                else //如果此时栈不空,可能有两种情况,1)栈正好剩下1个左括号和当前右括号配对 2)栈剩下不止1个左括号,
                {   
                    paranStack.pop();  
                    if (paranStack.empty())  //栈pop()之前正好剩下1个左括号,pop()之后,栈空了,此时group长度为indx-lastValidIndx  
                        maxLength = max(maxLength, indx - lastValidIndx + 1);  
                    else  //栈有pop()之前剩下不止1个左括号,此时额外多出的左括号使得新的group形成。如()(()())中index=4时,stack中有2个左括号  
                        maxLength = max(maxLength, indx - paranStack.top());  
                }  
            }  
        }  
        return maxLength;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值