LeeCode_394. 字符串解码(栈+递归)

算法学习 (门徒计划)1-3 递归与栈 学习笔记 3月18日,开课吧门徒计划算法课第三讲学习笔记。 本课讲递归和栈。 阅读详情

一、介绍

1.题目描述

题目链接:https://leetcode-cn.com/problems/decode-string/

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

2.测试样例

"3[a]2[bc]"  
# "aaabcbc"

"3[a2[c]]"
# "accaccacc"

"2[abc]3[cd]ef"
# "abcabccdcdcdef"

"abc3[cd]xyz"
# "abccdcdcdxyz"

"3[z]2[2[y]pq4[2[jk]e1[f]]]ef"
# "zzzyypqjkjkefjkjkefjkjkefjkjkefyypqjkjkefjkjkefjkjkefjkjkefef"

二、题解

1、字符栈🟡

在这道题中,涉及到括号匹配,想到栈,定义两个栈,一个n_stk记录数字,一个c_stk记录字符串。

  • 对于数字:由于数字可能>10,因此遇到数字要*10+x储存,当遇到左括号后推入栈并重置为0
  • 对于左括号:遇到左括号,将当前数字和答案推入栈,并分别重置。因为遇到左括号说明后面有新的重复字符串,因此将前面的字符串暂存进栈
  • 对于字符:加入到当前答案中
  • 对于右括号:取出前面的字符串,将当前字符串循环加入到答案中,循环次数为n_stk的栈顶

以3[a2[c]]为例。num=0,ans=""

  1. 遇到3,num=3
  2. 遇到左括号,数字3入栈,重置num=0。ans"“入栈,重置ans=”"
  3. 遇到a,ans=‘a’
  4. 遇到2,num=2
  5. 遇到左括号,数字2入栈,重置num=0。ans"a"入栈,重置ans=""
  6. 遇到c,ans=‘c’
  7. 遇到右括号,取出字符串栈栈顶,赋给ans_temp=“a”;取出数字栈栈顶,赋给k=2;循环k 次,在ans_temp后面加入k个ans。完成后更新ans为ans_temp,即ans=acc
  8. 遇到右括号,取出字符串栈栈顶,赋给ans_temp="";取出数字栈栈顶,赋给k=3;循环k 次,在ans_temp后面加入k个ans。完成后更新ans为ans_temp,即ans=accaccacc

参考链接:https://leetcode-cn.com/problems/decode-string/solution/zi-fu-chuan-jie-ma-by-leetcode-solution/416067

class Solution {
public:
    string decodeString(string s) {
        // 数字栈和字符栈
        stack<int> n_stk;
        stack<string> c_stk;
        int num=0,i=0,k;
        int n=s.length();
        string ans="",ans_temp;
        while(i<n){
            // 重复次数
            if(s[i]>='0'&&s[i]<='9')num=num*10+(s[i]-'0');
            // 字符加入当前ans
            else if(s[i]>='a'&&s[i]<='z'){
                ans=ans+s[i];
            }
            // 遇左括号两边入栈,两边重置
            else if(s[i]=='['){
                n_stk.push(num);
                num=0;
                c_stk.push(ans);
                ans="";
            }
            // 遇右括号循环将当前字符串加入到前面的字符串
            else{
                ans_temp=c_stk.top();k=n_stk.top();
                while(k--) ans_temp=ans_temp+ans;
                ans=ans_temp;
                c_stk.pop();n_stk.pop();
            }
            i++;
        }
        return ans;
    }
};

image-20210916151937537

2、字符串栈🟡

除了处理字符,我们还可以将栈定义为存入字符串,其中,将单个字符s[i]转为字符串的方式为

string ss(1,s[i])
  • 若为左括号或字母,压入字符串栈c_stk
  • 若为右括号,弹出左括号前的所有字符,按序组合,重复k次,
  • 若为数字,压入数字栈n_stk

以e3[a2[c]]为例

  • 遇e,压入c_stk
  • 遇3,压入n_stk
  • 遇[,压入c_stk
  • 遇2,压入n_stk
  • 遇[,压入c_stk
  • 遇c,压入n_stk
  • 遇],弹出 c,重复2次,得cc。将cc压入c_stk
  • 遇],弹出并组合 cc、a,得到acc,重复3次,得accaccacc,将其压入c_stk
  • 遍历结束,弹出剩余元素并组合,得到eaccaccacc
class Solution {
public:
    string decodeString(string s) {
        stack<int> n_stk;
        stack<string> c_stk;
        int n=s.length();
        int i=0,k;
        string ans="",t="",temp="";
        while(i<n){
            string ss(1,s[i]);
            // 左括号或字母入栈
            if(ss=="["||(ss>="a"&&ss<="z")){
                c_stk.push(ss);
            }
            // 右括号
            else if(ss=="]"){
                // 弹出左括号前的所有字符并按序组合
                while(c_stk.top()!="["){
                    temp=c_stk.top();
                    c_stk.pop();
                    t=temp+t;
                }
                temp=t;
                // 弹出左括号
                c_stk.pop();
                // 该串重复k次
                int k=n_stk.top();
                n_stk.pop();
                for(int i=1;i<k;i++) t=t+temp;
                // 处理完入栈
                c_stk.push(t);
                t="";
            }
            // 若为数字
            else{
                n_stk.push(getnum(s,i));
            }
            i++;
        }
        // 组合整个字符串
        while(!c_stk.empty()){
            temp=c_stk.top();
            c_stk.pop();
            t=temp+t;
        }
        return t;
    }
    // 次数计算,可能有多位
    int getnum(string s,int &x){
        int ans=0;
        while(s[x]>='0'&&s[x]<='9'){
            ans=ans*10+(s[x]-'0');
            x++;
        }
        x--;
        return ans;
    }
};

image-20210918230612391

3、递归🟡

对于该问题,每当遇到左括号,剩余的内容可以当做一个新的字符串处理。因此想到递归算法。

  • 对于数字:由于数字可能>10,因此遇到数字要*10+x储存
  • 对于左括号:遇到左括号,右移一个字符,递归处理左括号后面的字符
  • 对于字符:加入到当前答案中
  • 对于右括号:返回当前答案

以3[a2[c]]为例。第一层num1=0,第一层ans1=""

  1. 遇到3,第一层num1=3
  2. 遇到左括号,指针i右移后调用递归,即接下来处理a2[c]]
  3. 遇到a,第二层ans2=“a”
  4. 遇到2,第二层num2=2
  5. 遇到左括号,指针i右移后调用递归,即接下来处理c]]
  6. 遇到c,第三层ans3=“c”
  7. 遇到右括号,返回第三层ans3"c"为第二层的temp。在第二层的ans2后面加上num2个temp。即得到返回的temp=“c”,原ans2=“a”,加上2个temp后 ans2=“acc”。
  8. 遇到右括号,返回第二层ans2"acc"为第一层的temp。在第一层的ans1后面加上num1个temp。即得到返回的temp=“acc”,原ans1="",加上3个temp后 ans1=“accaccacc”。
  9. 循环结束,返回ans1

参考链接:https://leetcode-cn.com/problems/decode-string/solution/decode-string-fu-zhu-zhan-fa-di-gui-fa-by-jyd/

class Solution {
public:
    string src; 
    int n,i;

    string getString() {
        // 仅代表该层的ans和num
        string ans="";
        int num=0;
        while(i<n){
            // 记录数字
            if(src[i]>='0'&&src[i]<='9') num=num*10+(src[i]-'0');
            else if(src[i]=='['){
                i++;
                // 进入下一层递归
                string temp=getString();
                // while(num--) ans=ans+temp;
                for(int j=0;j<num;j++) ans=ans+temp;
                num=0;
            }
            // 返回
            else if(src[i]==']') return ans;
            else ans+=src[i];
            i++;
        }
        return ans;
    }

    string decodeString(string s) {
        src = s;
        n=src.length();
        i = 0;
        return getString();
    }
};

image-20210916162333678

力扣LeetCode 394题:字符串解码(栈,递归) 题目: 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 示例: s = “3[a]2[bc]”, 返回 “aaabcbc”. s = “3[a2 阅读详情

相关推荐

【LeetCode 热题100】394:字符串解码(详细解析)(Go语言版)

本文详细解析了 LeetCode 热题 394:字符串解码。题目要求对编码字符串如 `k[encoded_string]` 进行解码,其中 `encoded_string` 需重复 `k` 次。文章提供了两种解法:使用栈模拟和递归 DFS,并附有 Go 语言实现代码。栈解法通过数字栈与字符串栈记录状态,适合迭代;递归解法则利用函数调用处理嵌套结构,代码更简洁。两者时间复杂度均为 O(n),但递归需注意栈深度问题。文章还总结了解题注意事项及适用场景,帮助读者更好地掌握字符串嵌套解析技巧。

小韩的博客 1063

数据结构:栈和队列(Leetcode20. 有效的括号+225. 用队列实现栈+232. 用栈实现队列)

数据结构栈和队列

小青菜的博客 1039

LeetCode 394:字符串解码的递归与栈解法详解

在计算机科学中,栈(Stack)是一种基础且重要的数据结构,遵循后进先出(LIFO)原则,常用于处理具有嵌套或回溯性质的问题。其核心原理是通过压栈和出栈操作来管理程序状态或数据顺序。递归则是函数调用自身的一种编程技巧,本质上是系统调用栈的隐式应用,适用于解决可分解为相似子问题的情况。这两种技术在处理嵌套结构解析时展现出极高的技术价值,例如在编译器构建、数据反序列化和模板渲染等场景中,它们能高效地处理括号匹配、状态保存和层级展开。字符串解码问题(LeetCode 394)正是栈与递归思想的经典实战:给定形如`

weixin_31528001的博客 280

&LeetCode0394& 字符串解码

题目 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4...

weixin_40482465的博客 224

阿里数据集(cluster-trace-v2018)提取

阿里数据集提取 本数据集采用的是阿里集群数据集-2018 详情可参考该文献:https://blog.csdn.net/weixin_41988248/article/details/92431588 CSV数据集提取操作见:https://blog.csdn.net/lucky_shi/article/details/105321149 关于read_csv包的用法见:https://blog.csdn.net/dc19971118/article/details/107721340 从阿里数据集来看,我

5-StarrySky的博客 3339

Innovus 安装全过程

【代码】Innovus 安装全过程。

lmyynlbcy的博客 5531

卡特兰数问题

例题 一个足够大的栈的进栈序列为1,2,3,…,n时有多少个不同的出栈序列? 圆周上有2n个点,以这些点为端点连互不相交的n条弦,求不同的连法总数. 有n个结点,问总共能构成几种不同的二叉树. 如中序遍历,根结点第k个被访问到,则根结点的左子树有k-1个点、根结点的右子树有n-k个点。k的取值范围为1到n。【2015年腾讯实习生在线笔试题】 一个凸的n边形,用直线连接它的两个顶点使之分成多个三角形,每条直线不能相交,问一共有多少种划分方案。 有n+1个叶子的满二叉树的个数? 向左记为

jpphy0的博客 694

学习 考证 帆软 FCP-FineBI V6.0 考试经验

参加这个学习班,认识了新朋友,可能是我职业生涯中的一次重要体验,其实大家想想 IT 和 医生一样都是需要终身学习的。只是医生学习周期更长但是回报率也更高。大家觉的呢?

小 tom的博客 6223

算法刷题记录1

个人算法笔记

qq_52788258的博客 1073

LVGL 离线字体转换lv_font_conv本地安装

LVGL FONT CONV 离线版本

liu132641的专栏 3382

GEE:大面积研究区域数据分块导出,以解决内存限制和导出失败的问题

本文介绍了在Google Earth Engine (GEE)平台分块导出大面积研究区域数据的方法。针对直接导出大区域影像易失败的问题,作者提出通过网格分块技术进行处理。文章展示了完整的JavaScript代码示例,包含定义研究区域、加载ESA WorldCover数据集、设置分块参数(包括像素大小、分块尺寸)、创建网格系统、处理坐标转换等关键步骤。代码中还提供了错误处理和导出按钮功能,确保数据能可靠地分块导出到Google Drive。该方法有效解决了大区域数据导出时的内存限制问题,适用于全球范围的研究。

养乐多的博客 1184

lc 394字符串解码:递归 或 用栈模拟递归

方法时间复杂度空间复杂度适用场景递归O(n)O(m)代码简洁,适合嵌套层数较少的情况栈O(n)O(m)通用,适合所有情况不用递归O(n)O(m)通用,适合所有情况递归:代码简洁,但可能受递归深度限制。栈:显式使用栈,逻辑清晰,适合所有情况。不用递归:类似于栈方法,但用vector模拟栈,代码稍长但同样高效。推荐使用栈方法,因为它直观且高效。用户_uBiEPAi<s.size();i++) 我想让某条件成立时,i直接跳过i+1到i+2ChatGLM。

m0_68339197的博客 1002

基于Simulink的电动车PMSM能量泄放与回收系统仿真设计

摘要 本文设计了一个基于Simulink的电动车PMSM能量泄放与回收系统仿真模型。系统采用分层建模方案,包含永磁同步电机(PMSM)矢量控制、电池管理和泄放功率计算等核心模块。通过详细的参数计算和MATLAB脚本实现,模拟了电动车在制动时的能量回收过程。重点研究了泄放电阻的控制策略,提出基于母线电压和电池SOC的多目标优化算法,确保系统在保护硬件安全的同时最大化能量回收效率。仿真模型包含完整的数学推导和模块搭建指南,为电动车能量管理系统设计提供了有效的仿真验证平台。

huanghm88的专栏 193

LeetCode 394. 字符串解码 - 栈与递归DFS详解

题目描述:给定一个经过编码的字符串 s,编码规则为 k[encoded_string],表示其中方括号内的字符串正好重复 k 次。请你解码并返回该字符串。题目保证输入总是有效,嵌套形式如 3[a2[c]] 也是合法的;k 可能是多位数。原题链接:https://leetcode.cn/problems/decode-string/难度等级:Medium相关标签:栈、字符串、递归、DFS、栈模拟| 解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 | 适用场景 |

m0_52114506的博客 1148

【ITS模型】基于MATLAB的ITS宽带短波信道模型的建模和仿真

1.软件版本 MATLAB2010b 2.本算法理论知识 对短波信道建模具有里程碑意义的是沃特森在1970年发表的一篇文章,文章中提出了一种静态模型,并在大气中进行了实验验证。 此静态模型可以描述为高斯散射增益抽头延迟线模型,即Watterson模型。 Watterson信道模型是经典的窄带短波信道模型,在这个模型中,信道衰落是瑞利幅度分布,而在每种传播模式中多普勒扩展的功率谱满足高斯分布。Watterson模型没有定义延时扩展的形状,认为各个多径传输模式中不存在延时扩展。其...

FPGA/MATLAB学习教程/源码/项目合作开发 2757

android11.0 Launcher3 高端定制之循环滑动

待机界面可以向左、向右循环切换页面 效果图 修改清单 packages/apps/Launcher3/res/values-zh-rCN/strings.xml packages/apps/Launcher3/res/values/config.xml packages/apps/Launcher3/res/values/strings.xml packages/apps/Launcher3/res/xml/launcher_preferences.xml packages/apps/Launc

cczhengv 1544

LeetCode394——字符串解码

我的LeetCode代码仓:https://github.com/617076674/LeetCode 原题链接:https://leetcode-cn.com/problems/decode-string/ 题目描述: 知识点:栈、递归 思路一:利用栈这种数据结构 从左到右遍历所给字符串: 当遇到右括号时,我们需要利用栈将与该右括号相匹配的左括号找出来,并将两括号间的内容重复相应...

清风阁 2415

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java实现 LeetCode 394 字符串解码

394. 字符串解码 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 ...

南 墙 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

LeetCode-394. 字符串解码 递归思路

输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。并没有随着内层的执行而向后移动。导致内层处理完了,外层又从老位置开始,或者根本不知道跳到哪里。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数。给定一个经过编码的字符串,返回它解码后的字符串。,例如不会出现像 3a 或 2[4] 的输入。一开始看到题目的测试用例其实第一反应就是递归。不过我一开始做的时候有点碰壁 因为我将。中递归调用处理括号内部逻辑时,外层的。对下一层递归的返回值进行累加即可。,表示其中方括号内部的。

SoulruiA的博客 1277

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

【LeetCode】394、字符串解码

【代码】【LeetCode】394、字符串解码。

呆呆的猫的博客 1051

LeetCode394. 字符串解码

LeetCode394. 字符串解码

Love Peace 1208

【每日算法】 LeetCode 394. 字符串解码

摘要 LeetCode 394题考察字符串解码问题,核心是处理嵌套编码结构。本文提供了两种解法:栈解法(最优)和递归解法。栈解法使用双栈分别存储数字和字符串,时间复杂度O(n),空间复杂度O(n),适合处理深度嵌套;递归解法利用调用栈自然处理嵌套,代码更简洁但可能栈溢出。文章分析了两种方法的复杂度、优缺点,并列举了前端开发中的实际应用场景,如模板引擎解析、CSS预处理、JSON/XML解析等。掌握该算法有助于提升处理嵌套数据结构的能力,对前端开发具有重要意义。

LYFlied的博客 999

LeetCode: 394. 字符串解码 - Python

解压字符串 问题描述: 现在有一种字符串的压缩规则是这样的:k[string],表示string连续出现k 次(0 &lt; k &lt; 1000)。 比如:s = "ef3[a]2[bc]gh", 解压后的字符串为:"efaaabcbcgh",这种压缩也可以相互嵌套:s = "3[a2[c]]", 解压后为:"accaccacc"。 输入一个压缩的字符串s,请输出解压后的字符串。 输入都是严...

Growth Diary 3611

【力扣】394:字符串解码 | 栈|递归

好久没更新力扣了,今天考完科目二,终于有时间继续学习了。 题目描述 给定一个经过编码的字符串,返回它解码后的字符串。 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 s = "3[a]2[bc]", 返

Heart_for_Ling的博客 672

LeetCode-394. 字符串解码【栈 递归 字符串】

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。输入:s = “2[abc]3[cd]ef”输入:s = “abc3[cd]xyz”输入:s = “3[a]2[bc]”输入:s = “3[a2[c]]”输出:“accaccacc”时间复杂度:O(n)

zik的博客 760

LeetCode—394.字符串解码(Decode String)——分析及代码(C++)

二、分析及代码 1. 栈迭代 设计 2 个栈,分别存储 数字 和 字符串,遍历过程中针对不同情况进行处理: 1)遍历到数字,读取连续存储的数字并合并为一个整数,存入数字栈中; 2)遍历到字符,读取连续存储的字符并合并为一个字符串,若字符串栈非空且栈顶不是左括号,则和栈顶字符串合并。将字符串存入栈中; 3)遍历到左括号,存入字符串栈中,用于确认新字符串是否需和栈顶字符串合并; 4)遍历到右括号,读取两个栈顶的数字和字符串,进行解码,并根据字符串栈顶是否为左括号确认当前解码后的字符串是否需和栈顶合并。将字符串存

江南土豆的博客 876
上一篇: 修改hosts解决多网页加载失败/不显示/视频无法观看等问题
下一篇: LeeCode_739. 每日温度(暴力+栈)
Netceor
博客等级 码龄9年 1046粉丝 306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值