思路:栈 + 逐字符扫描
字符串只有 4 类有效字符:
“[”、
“]”、
“,”、数字(含负号
“-”)。
“[”:新建一层
“NestedInteger”,挂到栈顶那层的 list 里,自己再入栈
- 数字/负号:累加到
“num”,用
“sign” 记符号
“,” 或
“]”:数字收尾,包装成整数塞进当前层;遇到
“]” 再弹栈出层
- 开头不是
“[” → 整个串就是一个整数,直接
“parseInt”
class Solution {
public NestedInteger deserialize(String s) {
if (s == null || s.length() == 0) return null;
if (s.charAt(0) != ‘[’) { // 纯整数
return new NestedInteger(Integer.parseInt(s));
}
Deque<NestedInteger> stack = new ArrayDeque<>();
NestedInteger root = null;
int num = 0, sign = 1;
boolean hasNum = false; // 标记是否正在读数字
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '-') {
sign = -1;
} else if (Character.isDigit(c)) {
num = num * 10 + (c - '0');
hasNum = true;
} else if (c == '[') {
NestedInteger cur = new NestedInteger();
if (!stack.isEmpty()) stack.peek().add(cur); // 挂到父层
stack.push(cur);
if (root == null) root = cur; // 第一层即结果
} else if (c == ',' || c == ']') {
if (hasNum) { // 数字读完,加入当前层
stack.peek().add(new NestedInteger(sign * num));
num = 0; sign = 1; hasNum = false;
}
if (c == ']') stack.pop(); // 当前层结束
}
}
return root;
}
}
关键点
- 空 list 要能处理:
“[]”、
“[[]]” 时
“hasNum” 一直是 false,不往里加元素,直接入栈/出栈即可,无需特判 - 负数:
“-” 只改
“sign”,数字段靠
“hasNum” 判断边界 - root 的取法:只在
“[” 且
“root == null” 时记录第一个创建的层,避免弹栈后丢失
复杂度
- 时间
“O(n)”,每个字符扫一次 - 空间
“O(d)”,
“d” 为最大嵌套深度(栈高度)
已用
“324”、
“[123,[456,[789]]]”、
“[]”、
“[-1,[2,-3],[]]”、
“[[]]”、
“[123,456,[788,799,833],[[]],10,[]]” 全量验证通过。
递归写法(遇到
“[” 就递归解析子层)也能过,但栈写法没有递归深度风险,更推荐。

转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/m0_37843156/article/details/168332531




