1190. 反转每对括号间的子串

思路:
这个题之前做过也写过博客了。
当时的方法是遇到(,就将res字符串存放的字符串放入栈中,遇到)说明一个层次的字符串已经找到,就将当前res的字符串反转,并将栈里的top取出放在原res字符串前面,然后继续遍历s,如果遇到字母就加入res,否则就继续上述步骤,直到遍历完s。之前写的
这次的话用一个新的方法,
因为我们每次匹配一对()就要reverse里面的字符串,消耗多余的时间。
所以因为只是reverse那么我们反方向添加字符串就行了,所以我们采用的方法是每遇到(或者),我们都跳到它对应的)或(然后反转运动的方向,即可。
例如(u(love)i),遇到第一个(我们跳到最后一个),然后向左边取i,遇到)跳到第二个(,然后向右边取love,再遇到)再跳到第二个(,然后向左取u。就能得到iloveu了。因此我们只需O(n)的时间,不许再花费reverse的时间。

这里我们需要用栈来记录每对()的下标位置。具体做法就是遇到(就将下标放入栈里,遇到)就取出栈的下标,然后pair[i]=j,pair[j]=i即可存放()的位置。
然后我们每次找到(或)就通过pair数组找到对应的)或(,然后反转运行的方向即可。
代码:

class Solution {
public:
    string reverseParentheses(string s) {
        int n=s.length();
        vector<int> pair(n);
        stack<int> st;
        for(int i=0;i<n;++i){ //记录一对()的位置
            if(s[i]=='('){
                st.push(i); 
            }
            else if(s[i]==')'){
                int j=st.top();
                st.pop();
                pair[i]=j;
                pair[j]=i;
            }
        }
        string res;
        int  idx = 0,step=1; //通过step的正负来决定取值的方向,很妙
        while(idx<n){
            if(s[idx]=='('||s[idx]==')'){ 
                idx=pair[idx]; //跳转到对应()
                step = -step;  //反转取字母的方向
            }
            else{
                res.push_back(s[idx]);
            }
            idx += step;
        }
        return res;
    }
};
posted @ 2021-05-26 14:03  Mrsdwang  阅读(75)  评论(0编辑  收藏  举报