【dp、栈】找括号串中最长合法子串

思路: 是否合法,最简单判断方法是用栈。只有一种括号,栈中存放元素只需要左括号的下标。 每一次遇到),就把栈顶的一个左括号下标和当前下标一起压入vector中,将这个vector排序,就是所有合法子串的下标。遍历这个vector,找连续的最长值就可以。排序复杂度O(nlogn),除此之外遍历一次字符串,一次vector,O(n)。

int longestValidParentheses(string s) {
        stack<int> st;
        vector<int> index;
        int longest=0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='(') st.push(i);
            else{
                if(st.size()){
                    int tem=st.top();
                    st.pop();
                    index.push_back(tem);
                    index.push_back(i);
                }
            }
        }
        if(index.size()==0) return 0;
        sort(index.begin(),index.end());
        int now=0;
        for(int i=0;i<index.size()-1;i++){
            //cout<<index[i]<<' ';
            //cout<<index[i+1]<<' ';
            now++;
            //cout<<now<<endl;
            if(index[i+1]!=index[i]+1){
                longest=max(longest,now);
                now=0;
            }
        }
        now++;
        longest=max(longest,now);
        return longest;
    }

改良的stack解法:在想出上面解法的过程中,没用当前i 减去栈顶元素下标的原因是,遇到连续一串的()()(),没办法连起来;实际上这里只要加入一个小trick就好了:每一次遇到)的时候,先pop,再算i - stack.top(),  因为stack.top()这个时候,是前面最近一个还没被消掉的 (, 减去它就是当前最长串的长度。而当栈空的时候,就说明至此为止,前面所有的(都被消掉了(或者根本没有左括号),所以这个)是不配对的,把它的下标压进栈中,作为新的子串的起点前。

栈的最初要压入一个-1,相当于在最前面加一个dummy节点。

 int longestValidParentheses(string s) {
        int longest=0;
        stack<int> st;
        st.push(-1);
        for(int i=0;i<s.size();i++){
            if(s[i]=='(') st.push(i);
            else{
                st.pop();
                if(st.empty()){
                    st.push(i);
                }
                else{
                    longest=max(longest, i-st.top());
                }
            }
        }
        return longest;
    }

 

解法2: dp,count[i]表示 结束于i的有效子串长度。count[i] 的计算:

- s[i]=='(" , 一定0

- s[i]==')',

     -s[i-1]=='(', count[i]=count[i-2]+2;

     -s[i-1]==')',就是有可能嵌套,要看s[i-count[i-1]-1]是否为‘(“,若是,为合法的嵌套,要跟这个嵌套子串前面可能的最长串合并。count[i]=count[i-1]+count[i-count[i-1]-2]+2.

              -不是合法嵌套,在这个)处,应清零,count[i]=0;

int longestValidParentheses(string s) {
        if(!s.size()) return 0;
        int count[s.size()];
        int longest=0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='(') count[i]=0;
            else{
                if(i==0) count[i]=0;
                else if(s[i-1]=='('){
                    if(i-2>=0){
                        count[i]=count[i-2]+2;
                    }
                    else count[i]=2;
                }
                else{
                    if(i-count[i-1]-1>=0&&s[i-count[i-1]-1]=='('){
                        if(i-count[i-1]-2>=0){
                            count[i]=count[i-1]+count[i-count[i-1]-2]+2;
                        }
                        else count[i]=count[i-1]+2;
                    }
                    else{
                        count[i]=0;
                    }
                }
                longest=max(longest,count[i]);
            }
            
        }
        return longest;
    }

 

posted @ 2019-09-15 15:59  rarecu  阅读(516)  评论(0编辑  收藏  举报