• 代码题(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;
        }
    };
  • 相关阅读:
    最流行的javascript 代码规范
    jquery里阻止冒泡ev.stopPropagation()
    jquery里阻止冒泡ev.stopPropagation()
    响应式页面设计原理
    fromCharCode()的用法
    slice的用法
    java 反转数组
    java 一个数组的长度
    Java访问数组
    java 数组的定义
  • 原文地址:https://www.cnblogs.com/eilearn/p/9400575.html
Copyright © 2020-2023  润新知