• leetcode:32 最长有效括号


     题目

    给一个包含了'(' 和 ')'的字符串,求出其中最长有效括号的长度。

    做题情况:自己做出来,但做了较长的时间。

    思路:可以算得穷举法的时间复杂度为O(n^3)。虽然这题求的是最长的长度,但是用不了动态规划,因为无法找到一个合适的状态。考虑能不能在O(n)内实现,即遍历一次字符串。发现可以通过栈来做。具体方法如下:

            对于当前字符,如果是"(",直接压入栈中。如果是")",要分以下几种情况讨论:

    (1)如果当前栈为空,说明不存在与当前右括号配对的左括号,直接continue.

    (2)如果当前栈大小为1:

           a.如果栈顶元素是"(",则找到一个有效的括号序列,弹出栈顶元素,并压入这个序列的长度2;

           b.如果栈顶元素是数字,说明不存在与当前右括号配对的左括号,且由于插入了一个右括号,之前得到的括号序列无法更长,需要弹出栈顶元素。

    (3)如果当前栈的大小大于等于2:

           弹出栈顶元素

           a.如果是"(",则找到一个为2的有效序列,再检查栈顶元素,如果是数字,说明可以与前面找到的括号序列合并为一个更大的序列,与其相加后压入栈,否则直接将2压入栈;

           b.如果是数字,由于当前的栈大小大于等于2,则下一个栈的元素一定是“(”,弹出后压入合并后的序列长度,压之前再检查,如果栈顶元素还是为数字,则再合并,再压入。

    代码如下:

    public class Solution {
        public int longestValidParentheses(String s) {
            int n = s.length();
            Stack<Integer> stack = new Stack<Integer>();
            int max = 0;
            
            for(int i=0;i<n;i++){
                if(s.charAt(i)=='('){
                    stack.push(0);
                }else{
                    if(stack.size()==0){
                        continue;
                    }else if(stack.size()==1){
                        if(stack.pop()==0){
                            stack.push(2);
                            max = Math.max(max,2);
                        }
                    }else{
                        if(stack.peek()==0){
                            stack.pop();
                            int num = 2;
                            if(stack.peek()!=0){
                                num += stack.pop();
                            }
                            stack.push(num);
                            max = Math.max(max,num);
                        }else{
                            int temp = stack.pop();
                            stack.pop();
                            temp+=2;
                            if(!stack.isEmpty()&&stack.peek()!=0){
                                temp += stack.pop();
                            }
                            max = Math.max(max,temp);
                            stack.push(temp);
                        }
                    }
                }
            }
            
            return max;
        }
    }
  • 相关阅读:
    19面向对象--特殊成员
    18面向对象--成员和组合
    17面向对象--三大特性
    16异常处理
    15(os、random、sys、)(json、pickle )
    14python模块之re
    13正则表达式
    12内置函数补充,递归以及二分法。
    Linux环境ftp搭建及问题总结
    运维之路—linux忘记密码修改(rd.breake 方式)
  • 原文地址:https://www.cnblogs.com/coldyan/p/5921560.html
Copyright © 2020-2023  润新知