一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情。
题目描述
给定一个字符串 s 表示一个整数嵌套列表,实现一个解析它的语法分析器并返回解析的结果 NestedInteger 。
列表中的每个元素只可能是整数或整数嵌套列表
示例 1:
输入:s = "324",
输出:324
解释:你应该返回一个 NestedInteger 对象,其中只包含整数值 324。
示例 2:
输入:s = "[123,[456,[789]]]",
输出:[123,[456,[789]]]
解释:返回一个 NestedInteger 对象包含一个有两个元素的嵌套列表:
- 一个 integer 包含值 123
- 一个包含两个元素的嵌套列表:
i. 一个 integer 包含值 456
ii. 一个包含一个元素的嵌套列表
a. 一个 integer 包含值 789
提示:
- 1 <= s.length <= 5 * 104
- s 由数字、方括号 "[]"、负号 '-' 、逗号 ','组成
- 用例保证 s 是可解析的 NestedInteger
- 输入中的所有值的范围是 [-106, 106]
思路
之前做过类似的左右括号匹配的题目,核心思想就是出现右半括号']'的时候,跟它匹配的左半括号一定是在它左边离它最近的'['。所以,当出现左边括号的时候,我们可以做一步压栈,然后遇到右半括号的时候,做一步出栈,然后把这一对匹配上就好。这题其实也是类似的,但是这题有一个难点是,单独的数组也是要包装成一个NestedInteger对象,如果每个NestedInteger对象都有括号包起来,这题就没啥难度了。
所以,本题的关键是处理好','和']'的情况。','要注意它前面一个字符,如果是数字,就要把这个数字组装成一个NestedInteger对象;如果是字符,那一定是']',此时不用处理,因为前面遇到']'已经处理过了,不可能是其他情况。']'明确是一个对象的结束,需要弹出这个对象,并加入到父级对象中去。
Java版本代码
class Solution {
public NestedInteger deserialize(String s) {
// 只包含1个数字的情况先处理掉
if (!s.startsWith("[")) {
return new NestedInteger(Integer.parseInt(s));
}
Stack<NestedInteger> stack = new Stack<>();
char[] chars = s.toCharArray();
// 当前解析到的数字
int num = 0;
// 负数标识
boolean neg = false;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c == '[') {
NestedInteger ni = new NestedInteger();
stack.push(ni);
} else if (c == '-') {
neg = true;
} else if (Character.isDigit(c)) {
num = num * 10 + c - '0';
} else {
if (Character.isDigit(s.charAt(i - 1))) {
if (neg) {
num *= -1;
}
stack.peek().add(new NestedInteger(num));
}
num = 0;
neg = false;
if (c == ']' && stack.size() > 1) {
NestedInteger ni = stack.pop();
stack.peek().add(ni);
}
}
}
return stack.pop();
}
}