zoukankan      html  css  js  c++  java
  • 代码题(31)— 有效的括号、括号生成、最长有效括号

    1、20. 有效的括号

    给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

    有效字符串需满足:1、左括号必须用相同类型的右括号闭合。2、左括号必须以正确的顺序闭合。

    注意空字符串可被认为是有效字符串。

    示例 2:

    输入: "()[]{}"
    输出: true

    示例 4:

    输入: "([)]"
    输出: false
    

    示例 5:

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

    2、22. 括号生成

    给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

    例如,给出 = 3,生成结果为:

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

      这道题给定一个数字n,让生成共有n个括号的所有正确的形式,对于这种列出所有结果的题首先还是考虑用递归Recursion来解,由于字符串只有左括号和右括号两种字符,而且最终结果必定是左括号3个,右括号3个,所以我们定义两个变量left和right分别表示剩余左右括号的个数,如果在某次递归时,左括号的个数大于右括号的个数,说明此时生成的字符串中右括号的个数大于左括号的个数,即会出现')('这样的非法串,所以这种情况直接返回,不继续处理。如果left和right都为0,则说明此时生成的字符串已有3个左括号和3个右括号,且字符串合法,则存入结果中后返回。如果以上两种情况都不满足,若此时left大于0,则调用递归函数,注意参数的更新,若right大于0,则调用递归函数,同样要更新参数。

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

    3、32. 最长有效括号

    给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

    示例 1:

    输入: "(()"
    输出: 2
    解释: 最长有效括号子串为 "()"
    

    示例 2:

    输入: ")()())"
    输出: 4
    解释: 最长有效括号子串为 "()()"

      这里我们还是借助栈来求解,需要定义个start变量来记录合法括号串的起始位置,我们遍历字符串,如果遇到左括号,则将当前下标压入栈,如果遇到右括号,如果当前栈为空,则将下一个坐标位置记录到start,如果栈不为空,则将栈顶元素取出,此时若栈为空,则更新结果和i - start + 1中的较大值,否则更新结果和i - 栈顶元素中的较大值。

    class Solution {
    public:
        int longestValidParentheses(string s) {
            int res = 0;
            int start = 0;
            stack<int> st;
            for(int i=0;i<s.size();++i)
            {
                if(s[i] == '(')
                    st.push(i);
                else if(s[i] == ')')
                {
                    if(st.empty())
                        start = i+1;
                    else
                    {
                        st.pop();
                        if(st.empty())
                            res = max(res, i-start+1);
                        else
                            res = max(res,i-st.top());
                    }
                }
            }
            return res;
        }
    };
    class Solution {
    public:
        int longestValidParentheses(string s) {
            int res = 0;
            int start = 0;
            stack<int> st;  //记录左括号的位置
            for(int i=0;i<s.size();++i)
            {
                if(s[i] == '(')  //只有“(”入栈,右括号不入栈
                    st.push(i);
                else if(s[i] == ')')
                {
                    if(st.empty()) //如果此时栈里左括号已经被消耗完了,没有额外的左括号用来配对当前的右括号了,那么当前的右括号就被单出来了,表明当前子串可以结束了,此时的右括号也成为了下一个group的分界点,此时右括号下标为index,所以下一个group的起始点为index+1,相当于skip掉当前的右括号。
                        start = i+1;
                    else //如果此时栈不空,可能有两种情况,1)栈正好剩下1个左括号和当前右括号配对 2)栈剩下不止1个左括号
                    {
                        st.pop();
                        if(st.empty()) //栈pop()之前正好剩下1个左括号,pop()之后,栈空了,此时group长度为pos-lastPos
                            res = max(res, i-start+1);
                        else
                            res = max(res,i-st.top());//栈有pop()之前剩下不止1个左括号,此时额外多出的左括号使得新的group形成
                    }
                }
            }
            return res;
        }
    };
  • 相关阅读:
    织梦开发——相关阅读likeart应用
    织梦标签教程
    织梦专题调用代码
    HIT 2543 Stone IV
    POJ 3680 Intervals
    HIT 2739 The Chinese Postman Problem
    POJ 1273 Drainage Ditches
    POJ 2455 Secret Milking Machine
    SPOJ 371 Boxes
    HIT 2715 Matrix3
  • 原文地址:https://www.cnblogs.com/eilearn/p/9400575.html
Copyright © 2011-2022 走看看