1190. 反转每对括号间的子串(栈|splay)[通俗易懂]

1190. 反转每对括号间的子串(栈|splay)[通俗易懂]给出一个字符串 s(仅含有小写英文字母和括号)。请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。注意,您的结果中 不应 包含任何括号。示例 1:输入:s = “(abcd)”输出:”dcba”示例 2:输入:s = “(u(love)i)”输出:”iloveu”示例 3:输入:s = “(ed(et(oc))el)”输出:”leetcode”示例 4:输入:s = “a(bcdefghijkl(mno)p)q”输出:”apmnolkjihgf

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

给出一个字符串 s(仅含有小写英文字母和括号)。

请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。

注意,您的结果中 不应 包含任何括号。

示例 1:

输入:s = "(abcd)"
输出:"dcba"
示例 2:

输入:s = "(u(love)i)"
输出:"iloveu"
示例 3:

输入:s = "(ed(et(oc))el)"
输出:"leetcode"
示例 4:

输入:s = "a(bcdefghijkl(mno)p)q"
输出:"apmnolkjihgfedcbq"
 

提示:

0 <= s.length <= 2000
s 中只有小写英文字母和括号
我们确保所有括号都是成对出现的

class Solution { 
   
public:
    stack<char>s1;
    queue<char>s2;
    bool isalpha(char a){ 
   
        return a >= 'a' && a <= 'z';
    }
    string reverseParentheses(string s) { 
   
        for(auto &a : s){ 
   
            if(isalpha(a) || a == '('){ 
   
                s1.push(a);
            }
            else{ 
   
                while(s1.top() != '('){ 
   
                    s2.push(s1.top());
                    s1.pop();
                }
                s1.pop();
                while(s2.size()){ 
   
                    s1.push(s2.front());
                    s2.pop();
                }
            }
        }
        string t = "";
        while(s1.size()){ 
   
            t.append(1,s1.top());
            s1.pop();
        }
        reverse(t.begin(),t.end());
        return t;
    }
};
  1. splay
#define lson tr[u].s[0]
#define rson tr[u].s[1]
const int N = 2010;

class Solution { 
   
public:
    struct node{ 
   
        int p,v;
        int s[2];
        int size,flag;
        void init(int _v,int _p){ 
   
            v = _v,p = _p;
            flag = 0,size = 1;
        }
    }tr[N] = { 
   0};
    int root = 0,ctx = 0;
    void pushdown(int u){ 
   
        if(tr[u].flag){ 
   
            swap(tr[lson].s[0],tr[lson].s[1]);
            swap(tr[rson].s[0],tr[rson].s[1]);
            tr[lson].flag ^= 1;
            tr[rson].flag ^= 1;
            tr[u].flag = 0;
        }
    }
    void pushup(int u){ 
   
        tr[u].size = tr[lson].size + tr[rson].size + 1;
    }
    void rotate(int x){ 
   
        int y = tr[x].p,z = tr[y].p;
        int k = tr[y].s[1] == x;//k是1 则x是y的右儿子,k是0,则x是y的左儿子
        tr[z].s[tr[z].s[1] == y] = x,tr[x].p = z;
        tr[y].s[k] = tr[x].s[k ^ 1],tr[tr[x].s[k ^ 1]].p = y;
        tr[x].s[k ^ 1] = y,tr[y].p = x;
        pushup(y);pushup(x);
    }
    void splay(int x,int k){ 
           //将x节点旋转到k节点下面
        while(tr[x].p != k){ 
   
            int y = tr[x].p,z = tr[y].p;
            if(z != k){ 
   
                if((tr[z].s[1] == y) ^ (tr[y].s[1] == x))rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
        if(!k)root = x;
    }
    void insert(char a){ 
   
        int u = root,p = 0;
        while(u)pushdown(u),p = u,u = tr[u].s[1];
        u = ++ ctx;
        if(p)tr[p].s[1] = u;
        tr[u].init(a,p);
        splay(u,0);
    }
    int get_th(int k){ 
   
        int u = root;
        while(true){ 
   
            pushdown(u);
            if(tr[lson].size >= k)u = lson;
            else if(tr[lson].size + 1 == k)return u;
            else k -= tr[lson].size + 1,u = rson;
        }
        return u;
    }
    string ans = "";
    void output(int u){ 
   
        pushdown(u);
        if(lson)output(lson);
        if(tr[u].v != 0)ans.append(1,tr[u].v);
        if(rson)output(rson);
    }
    void build(int L,int R,int x){ 
   
        int u =  ++ ctx;
        tr[u].init(x,R);
        tr[R].s[0] = u;
        pushup(R);pushup(L);
    }
    stack<int>ss;
    string reverseParentheses(string s) { 
   
        int end = -1;
        insert(0);
        insert(0);
        for(int i = 0;i < s.size();i ++){ 
   
            if(s[i] == '('){ 
   
                ss.push(end + 1);
            }
            else if(s[i] == ')'){ 
   
                int L = ss.top() - 1;
                ss.pop();
                int R = end + 1;
                L = get_th(L + 2);R = get_th(R + 2);
                splay(L,0);splay(R,L);
                int ls = tr[R].s[0];
                tr[ls].flag ^= 1;
                swap(tr[ls].s[0],tr[ls].s[1]);
            }
            else{ 
   
                char x = s[i];
                int L = end,R = end + 1;
                L = get_th(L + 2);R = get_th(R + 2);
                splay(L,0);splay(R,L);
                build(L,R,x);
                end ++;
            }
        }
        output(root);
        return ans;
    }
};
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/169062.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月11日 下午7:16
下一篇 2022年8月11日 下午7:36


相关推荐

  • 腾讯元宝 – 腾讯打造的智能问答与办公AI助手

    腾讯元宝 – 腾讯打造的智能问答与办公AI助手

    2026年3月13日
    2
  • python3 global和nonlocal 关键字

    python3 global和nonlocal 关键字python 变量引用顺序 从当前作用域开始寻找变量 如果没找到就往上一层作用域寻找 没找到就再上一层 即 当前作用域局部变量 gt 外层作用域变量 gt 再外层作用域变量 gt gt 当前模块全局变量 gt pyhton 内置变量 global 全局变量 nonlocal 外层嵌套函数的变量使用总结 局部作用域改变全局变量用 global global 同时还可以定义新的

    2026年3月19日
    2
  • 8421BCD码 5421BCD码 余三码 格雷码 余三循环码之间的关系,转换以及简易方法

    8421BCD码 5421BCD码 余三码 格雷码 余三循环码之间的关系,转换以及简易方法8421BCD码5421BCD码余三码格雷码余三循环码之间的关系,转换以及简易方法1.有权码和无权码的包括2.各种码值的介绍8421码的简介8421码又称为BCD码,是十进代码中最常用的一种。在这种编码方式中,每一位二值代码的“1”都代表一个固定数值。将每位“1”所代表的 二进制数加起来就可以得到它所代表的十进制数字。因为代码中从左至右看每一位“1”分别代表数字“8”“4…

    2025年8月1日
    6
  • 机器学习笔记之SVM(SVR)算法

    机器学习笔记之SVM(SVR)算法学过 SVM 后 看了那么多别人的文章 是时候自己总结一波了 权当写的笔记供自己日后再回顾吧 PS 结合自己在工作过程中 我用 SVR 做股票预测 用到的知识来写的 不会很全面 若有些知识这里没提及读者可自行查找 1 概述支持向量机 supportvecto 是一种分类算法 但是也可以做回归 根据输入的数据不同可做不同的模型 若输入标签为连续值则做回归 若输入标签为分类值则做

    2026年3月18日
    3
  • Windows 定时执行脚本[通俗易懂]

    Windows 定时执行脚本[通俗易懂]Windows定时执行脚本1、参考资料windows设置定时执行脚本2、解决办法由于Windows系统,无法使用Linux下强大的crontab命令,所以该定时任务也是针对Windo系统的具体操作步骤右击【我的电脑】,选择【管理】在【任务计划程序】面板中点击【创建基本任务】输入任务的【名称】和【描述】当然是希望每天自动执行防疫打卡啦~设置每天执行任务的时间,以及每隔几天执行一次该任务选择【启动程序】选择启动程序的startup.bat

    2022年7月17日
    61
  • java中遍历数组_java遍历object数组

    java中遍历数组_java遍历object数组遍历数组目录遍历数组三种方式:for循环遍历foreach语句遍历Arrays工具类中toString静态方法遍历Arrays.deepToString()与Arrays.toString()的区别Java中对Array数组的常用操作(了解即可)三种方式: for for-each, toString 题目描述给一个数组:intArr={{5,7,15},{8,4,11},{3,6,13}};for循环遍历通常遍历数组都是使用f

    2026年1月21日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号