文章目录
前言
本题主要考查 栈 的使用。
提示:以下是本篇文章正文内容,编程语言为Java
一、题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入
示例 1:
输入:s = "3[a]2[bc]"
输出:"aaabcbc"
链接:字符串解码
二、解题思路
本题和 有效括号 原理类似,都是在遇到右括号时执行一些出栈操作,对于其它字符执行入栈操作,但是本题在出栈处理上更加复杂。主要思路如下:
1. 我们遍历字符串 s
,当字符不是 ]
时,直接入栈(注意,需要将字符转为字符串后入栈);
2. 当遍历到字符是 ]
时,我们需要执行出栈的一些处理,后续的字符必然是 132[abc
(c为栈顶) 字母、[ 、数字 的出栈顺序,因此可以按顺序分为三步:
1)处理字母。我们需要将字母按出栈的倒序组合成一个字符串,即 c出栈——b出栈——a出栈,最后组合成字符串 s1 = "abc"
.
2)处理 [ 。直接出栈即可。
3)处理数字 。我们同样需要将数字按出栈的倒序组合成一个字符串,即 2出栈——3出栈——1出栈,最后组合成字符串 s2 = "132"
,转为整数 cnt=132
.
3. 当上述处理完后,我们就获得了字符串以及字符串重复的次数,我们将 s1
重复 cnt
次后组合成新的字符串 s3
,并入栈,继续下一次迭代。
最后栈内元素的出栈倒序组合成的字符串就是本题的答案。
三、示例代码
class Solution {
public String decodeString(String s) {
Deque<String> st=new LinkedList<>();
for(char c:s.toCharArray()){
String s0=Character.toString(c);
//非 ] 直接入栈
if(!s0.equals("]")){
st.push(s0);
continue;
}
//遇到 ] 进行出栈处理
StringBuilder sb1=new StringBuilder();
StringBuilder sb2=new StringBuilder();
char tmp=st.peek().charAt(0);
//处理字母
while(tmp>='a' && tmp <='z'){
sb1.insert(0,st.pop());
tmp=st.peek().charAt(0);
}
//处理 [
if(tmp=='['){
st.pop();
tmp=st.peek().charAt(0);
}
//处理数字
while(tmp>='0' && tmp<='9'){
sb2.insert(0,st.pop());
if(st.isEmpty()) break;
tmp=st.peek().charAt(0);
}
int cnt=Integer.parseInt(sb2.toString());
StringBuilder sb3=new StringBuilder();
//字符串重复 cnt 次
while(cnt>0){
sb3.append(sb1);
cnt--;
}
//新字符串入栈
st.push(sb3.toString());
}
StringBuilder ans=new StringBuilder();
while(!st.isEmpty()){
ans.insert(0,st.pop());
}
return ans.toString();
}
}
总结
本题考查了 栈 的使用,通过出栈和入栈的相关处理完成字符串的解码。本题大量使用了 StringBuilder
。常用方法如下:
1)初始化。StringBuilder sb=new StringBuilder()
2)尾部添加字符串。sb.append(s)
3)指定位置添加字符串。sb.insert(i,s)
4)指定位置删除字符串。sb.delete(i,j)
5)转为字符串类型。sb.toString()