力扣394(java)-字符串解码(中等)
题目:
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:
输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:
输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:
输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"
提示:
- 1 <= s.length <= 30
- s 由小写英文字母、数字和方括号 '[]' 组成
- s 保证是一个 有效 的输入。
- s 中所有整数的取值范围为 [1, 300]
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/decode-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
本题是嵌套的括号,需要生成字符串,故利用栈先进后出的特点来解决问题,定义两个栈,一个栈numstack用来存放数字,一个栈restack用来存放字符。
遍历字符串s的每个字符c:
1.当c为数字字符时,将数字字符转换为数字,并取出连续的数字num;
2.当c为字母时,将其放在临时存放字符串的StringBuilder res尾部中;
3.当c为左括号 '['时:
- 将上一次计算出的数字num压入栈numstack中;
- 将上一次存放在res中的临时结果压入栈restsack中;
- 然后重置num和临时res,给下一次遇到 '['使用
4.当c为右括号 ']' 时:
- 取出上次压入restack中的内容;
- 计算当前 []中重复的字符串;
- 进行拼接
5.返回字符串res。
举例: 3[a2[c2[ab]]] (只是模拟,写的不是很规范)
两个栈numstack和restack, StringBuilder res存储结果
i = 0时,s.charAt(i) = 3, num = 3;
i=1时,s.charAt(i) = '[':
- 3入栈:numstack = 3
- restack为空
- 重置:num = 0,res 为空
i=2时,s.charAt(i) = a,res=(a);
i=3时,s.charAt(i) = 2, num = 2;
i=4时,s.charAt(i) = '[':
- 2入栈:numstack 为(3,2)
- 将res里面的字符加入restack,restack为(a)
- 重置:num = 0,res 为空
i=5时,s.charAt(i) =c ,res=(c);
i=6时,s.charAt(i) = 2,num=2;
i=7时,s.charAt(i) = '[':
- 2入栈:numstack为(3,2,2)
- 将res里面的字符加入restack,restack为(a,c)
- 重置:num = 0,res 为空
i=8,s.charAt(i) =a,res =(a);
i=9,s.charAt(i) =b,res =(ab);
i=10时,s.charAt(i) = ']':
- 获取上一个倍数:numstack.pollLast() = 2(2就删除了,numstack只有3,2了);
- temp中添加两次res:即为abab;
- 与括号外的c合并就变成res = cabab(restack只有a了);
i=11时,s.charAt(i) = ']':
- 获取上一个倍数:numstack.pollLast() = 2(2就删除了,numstack只有3);
- temp中添加两次res:即为cababcabab;
- 与括号外的a合并就变成res = acababcabab(restack为空了);
i=12时,s.charAt(i) = ']':
- 获取上一个倍数:numstack.pollLast() = 3(numstack为空了);
- temp中添加三次res:即为acababcababacababcababacababcabab;
- restack为空,没法合并了
最终将res转换成字符串"acababcabab acababcababacababcabab"。
代码:
1 class Solution { 2 public String decodeString(String s) { 3 //定义两个栈用来存放倍数和字符 4 Deque<Integer> numstack = new ArrayDeque<>(); 5 Deque<StringBuilder> restack = new ArrayDeque<>(); 6 //拼接数字 7 int num = 0; 8 //存放结果 9 StringBuilder res = new StringBuilder(); 10 11 for(char c : s.toCharArray()){ 12 //遇到数字就压入数字栈 13 if(c >= '0' && c <= '9'){ 14 //取出连续的数字 15 num = num * 10 + c - '0'; 16 }else if(c == '['){ 17 //遇到左括号 18 //将上次计算出的数字压栈 19 numstack.addLast(num); 20 //将上一次的倍数后的结果字符存入字符栈 21 restack.addLast(res); 22 //重置数字和结果 23 num = 0; 24 res = new StringBuilder(); 25 }else if(c == ']'){ 26 StringBuilder temp = new StringBuilder(); 27 //获取倍数 28 int count = numstack.pollLast(); 29 //进行循环当前字符,拼接到上一次结果中 30 for(int i = 0; i < count; i++){ 31 temp.append(res); 32 } 33 //与括号外的合并 34 res = restack.pollLast().append(temp); 35 }else{ 36 res.append(c); 37 } 38 } 39 return res.toString(); 40 } 41 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)