leetcode-迷你语法分析器

122 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第21天,点击查看活动详情

题目描述

给定一个字符串 s 表示一个整数嵌套列表,实现一个解析它的语法分析器并返回解析的结果 NestedInteger 。
列表中的每个元素只可能是整数或整数嵌套列表
  示例 1:
输入:s = "324",
输出:324
解释:你应该返回一个 NestedInteger 对象,其中只包含整数值 324。

示例 2:
输入:s = "[123,[456,[789]]]",
输出:[123,[456,[789]]]
解释:返回一个 NestedInteger 对象包含一个有两个元素的嵌套列表:

  1. 一个 integer 包含值 123
  2. 一个包含两个元素的嵌套列表:
    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();
    }
}