LeetCode算法题(Go语言实现)_26
题目
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
一、代码实现
func decodeString(s string) string {
numStack := []int{}
strStack := []string{}
currStr := ""
num := 0
for _, ch := range s {
if ch >= '0' && ch <= '9' {
num = num*10 + int(ch-'0') // 处理多位数
} else if ch == '[' {
numStack = append(numStack, num)
strStack = append(strStack, currStr)
num = 0
currStr = "" // 重置状态
} else if ch == ']' {
repeat := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]
prevStr := strStack[len(strStack)-1]
strStack = strStack[:len(strStack)-1]
currStr = prevStr + strings.Repeat(currStr, repeat) // 拼接结果
} else {
currStr += string(ch) // 累积字符
}
}
return currStr
}
二、算法分析
1. 核心思路
- 栈结构特性:利用双栈(数字栈和字符串栈)处理嵌套结构:
- 数字栈存储重复次数
k
- 字符串栈存储括号外的累积结果
- 数字栈存储重复次数
- 动态构建:遍历时根据字符类型更新状态:
- 遇到数字时构建多位数(如
100
由1
、0
、0
组成) - 遇到
[
时缓存当前状态并重置 - 遇到
]
时弹栈并生成重复字符串
- 遇到数字时构建多位数(如
2. 关键步骤
- 数字解析:连续数字字符转换为整型(如
"123"
→123) - 状态缓存:左括号触发压栈操作,保存当前字符串和重复次数
- 字符串生成:右括号触发弹栈,拼接重复后的字符串
3. 复杂度
指标 | 值 | 说明 |
---|---|---|
时间复杂度 | O(n) | 单次遍历,每个字符处理一次 |
空间复杂度 | O(n) | 栈深度与嵌套层数正相关 |
三、图解示例
四、边界条件与扩展
1. 特殊场景验证
- 无括号字符串:
abc
→ 直接返回原字符串 - 单层嵌套:
3[a]
→aaa
- 多层嵌套:
2[3[cd]]
→cdcdcdcdcdcd
- 混合嵌套:
ab2[c3[d]e]
→abcdddecddde
2. 多语言实现
# Python实现(栈+字符串拼接)
def decodeString(s):
num_stack, str_stack = [], []
curr_str, num = "", 0
for ch in s:
if ch.isdigit():
num = num * 10 + int(ch)
elif ch == '[':
num_stack.append(num)
str_stack.append(curr_str)
num, curr_str = 0, ""
elif ch == ']':
curr_str = str_stack.pop() + curr_str * num_stack.pop()
else:
curr_str += ch
return curr_str
// Java实现(StringBuilder优化)
public String decodeString(String s) {
Stack<Integer> numStack = new Stack<>();
Stack<StringBuilder> strStack = new Stack<>();
StringBuilder curr = new StringBuilder();
int num = 0;
for (char ch : s.toCharArray()) {
if (Character.isDigit(ch)) {
num = num * 10 + (ch - '0');
} else if (ch == '[') {
numStack.push(num);
strStack.push(curr);
curr = new StringBuilder();
num = 0;
} else if (ch == ']') {
StringBuilder temp = strStack.pop();
int repeat = numStack.pop();
temp.append(curr.toString().repeat(repeat));
curr = temp;
} else {
curr.append(ch);
}
}
return curr.toString();
}
五、总结与扩展
1. 核心创新点
- 双栈协同:数字栈与字符串栈分离,逻辑清晰
- 线性时间复杂度:单次遍历即完成复杂嵌套结构的解析
2. 扩展应用
- 模板引擎:处理类似
{{repeat}}
的嵌套标签 - JSON/XML解析:处理层级嵌套的数据结构
- 数学表达式计算:扩展支持括号优先级运算
3. 性能优化方向
- 预分配内存:根据输入长度预初始化栈容量
- 字符串构建优化:使用
strings.Builder
(Go)/StringBuilder
(Java)减少拼接开销