上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

力扣

guduadmin211月前

题目

给你一个只包含 ‘(’ 和 ‘)’ 的字符串 s s s,找出最长有效(格式正确且连续)括号子串的长度。

方法

动态规划

  • d p [ i ] dp[i] dp[i] 表示以 s [ i ] s[i] s[i] 结尾的最长有效括号的长度
  • 如果 s [ i ] s[i] s[i] 为左括号,则 d p [ i ] = 0 dp[i] = 0 dp[i]=0
  • 如果 s [ i ] s[i] s[i] 为右括号,
    • 若 s [ i − 1 ] s[i-1] s[i−1] 为左括号, 则 d p [ i ] = d p [ i − 2 ] + 2 dp[i] = dp[i-2] + 2 dp[i]=dp[i−2]+2
    • 若 s [ i − 1 ] s[i-1] s[i−1] 为右括号,
      • 若 s [ i − 1 − d p [ i − 1 ] ] s[i-1-dp[i-1]] s[i−1−dp[i−1]] 为左括号,则 d p [ i ] = d p [ i − 1 ] + d p [ i − 2 − d p [ i − 1 ] ] + 2 dp[i] = dp[i-1] + dp[i-2-dp[i-1]] + 2 dp[i]=dp[i−1]+dp[i−2−dp[i−1]]+2
      • 若 s [ i − 1 − d p [ i − 1 ] ] s[i-1-dp[i-1]] s[i−1−dp[i−1]] 为右括号,则 d p [ i ] = 0 dp[i] = 0 dp[i]=0

        • 始终保持栈底元素为最后一个没有被匹配的右括号的下标,这样的做法主要是考虑了边界条件的处理,栈里其他元素维护左括号的下标:

          • 对于遇到的每个‘(’ ,我们将它的下标放入栈中
          • 对于遇到的每个‘)’,我们先弹出栈顶元素表示匹配了当前右括号:
            • 如果栈为空,说明当前的右括号为没有被匹配的右括号,我们将其下标放入栈中来更新我们之前提到最后一个没有被匹配的右括号的下标
            • 如果栈不为空,当前右括号的下标减去栈顶元素即为以该右括号为结尾的最长有效括号的长度

              我们从前往后遍历字符串并更新答案即可。

            • 需要注意的是,如果一开始栈为空,第一个字符为左括号的时候我们会将其放入栈中,这样就不满足提及的最后一个没有被匹配的右括号的下标,为了保持统一,我们在一开始的时候往栈中放入一个值为 − 1 -1 −1 的元素

              两次遍历

              • 从左往右遍历字符串:
                • 当遇到左括号时, l e f t left left 加一;当遇到右括号时, r i g h t right right 加一;
                • 当 l e f t = = r i g h t left == right left==right,更新一次最长有效括号的长度
                • 当 l e f t < r i g h t left < right left
                • 从右往左遍历字符串:
                  • 当遇到左括号时, l e f t left left 加一;当遇到右括号时, r i g h t right right 加一;
                  • 当 l e f t = = r i g h t left == right left==right,更新一次最长有效括号的长度
                  • 当 l e f t > r i g h t left > right left>right,将两个变量清零;

                    代码

                    class Solution {
                    public:
                        int longestValidParentheses(string s) {
                            // int n = s.size();
                            // stack stk;
                            // vector> ind_list;
                            // stk.push(-1);
                            // int ret = 0;
                            // for(int i = 0; i < n; i++){
                            //     if(s[i] == '('){
                            //         stk.push(i);
                            //     }
                            //     else{
                            //         if(stk.top() != -1){
                            //             if(ind_list.size()>0 && stk.top()-ind_list[ind_list.size()-1][1] < 0){
                            //                 ind_list[ind_list.size()-1][0] = stk.top();
                            //                 ind_list[ind_list.size()-1][1] = i;
                            //             }
                            //             else
                            //                 ind_list.push_back({stk.top(), i});
                            //             if(ind_list.size()>=2){
                            //                 int r1 = ind_list[ind_list.size()-2][1];
                            //                 int l2 = ind_list[ind_list.size()-1][0];
                            //                 int r2 = ind_list[ind_list.size()-1][1];
                            //                 if(l2-r1 == 1){
                            //                     ind_list[ind_list.size()-2][1] = r2;
                            //                     ind_list.pop_back();
                            //                 }
                            //             }
                            //             stk.pop();
                            //         }
                            //     }
                            // }
                            // for(int i = 0; i < ind_list.size(); i++){
                            //     ret = max(ret, ind_list[i][1]-ind_list[i][0]+1);
                            // }
                            // return ret;
                            // 1 dp
                            // int n = s.size();
                            // vector dp(n, 0);
                            // int ret = 0;
                            // for(int i = 1; i < n; i++){
                            //     if(s[i] == ')' && s[i-1] == '('){
                            //         if(i >= 2)
                            //             dp[i] = dp[i-2] + 2;
                            //         else
                            //             dp[i] = 2;
                            //     }
                            //     else if(s[i] == ')' && s[i-1] == ')'){
                            //         if(i-1-dp[i-1] >= 0 && s[i-1-dp[i-1]] == '('){
                            //             if(i-2-dp[i-1] >= 0)
                            //                 dp[i] = dp[i-1] + 2 + dp[i-2-dp[i-1]];
                            //             else    
                            //                 dp[i] = dp[i-1] + 2;
                            //         }
                            //     }
                            //     ret = max(ret, dp[i]);
                            // }
                            // return ret;
                            // 2 stack
                            int n = s.size();
                            stack stk;
                            stk.push(-1);
                            int ret = 0;
                            for(int i = 0; i < n; i++){
                                if(s[i] == '('){
                                    stk.push(i);
                                }
                                else{
                                    stk.pop();
                                    if(stk.empty()){
                                        stk.push(i);
                                    }
                                    else{
                                        ret = max(ret, i-stk.top());
                                    }
                                }
                            }
                            return ret;
                            // 3
                            // int n = s.size();
                            // int left = 0, right = 0;
                            // int ret = 0;
                            // for(int i = 0; i < n; i++){
                            //     if(s[i] == '('){
                            //         left++;
                            //     }
                            //     else{
                            //         right++;
                            //     }
                            //     if(left == right){
                            //         ret = max(ret, 2*left);
                            //     }
                            //     else if(right > left){
                            //         right = 0;
                            //         left = 0;
                            //     }
                            // }
                            // left = 0; right = 0;
                            // for(int i = n-1; i >= 0; i--){
                            //     if(s[i] == '('){
                            //         left++;
                            //     }
                            //     else{
                            //         right++;
                            //     }
                            //     if(left == right){
                            //         ret = max(ret, 2*left);
                            //     }
                            //     else if(right < left){
                            //         right = 0;
                            //         left = 0;
                            //     }
                            // }
                            // return ret;
                        }
                    };
                    

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦见掏耳朵是什么预兆  梦见上门牙掉了预示着什么  国家为什么禁八字算命