夯实算法-迷你语法分析器

83 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 18 天,点击查看活动详情

题目:LeetCode

给定一个字符串 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<=51041 <= s.length <= 5 * 10^4
  • s 由数字、方括号 "[]"、负号 '-' 、逗号 ','组成
  • 用例保证 s 是可解析的 NestedInteger
  • 输入中的所有值的范围是 [-10610^6, 10610^6]

解题思路

字符串是递归定义的,我们自然也可以递归求解,当然,我们不用完全依赖递归函数,可以通过栈来模拟,从左到右遍历字符串:

  • 如果当前的值是[,则说明我们需要创建一个NestedInteger来接收后面的值,那么就要new NestedInteger() 并放到栈顶
  • 如果当前的值是],则说明我们栈顶的NestedInteger已经构建完毕了,我们可以把他pop出来,并将他的值添加到当前栈顶(当前栈顶已经是另一个NestedInteger了)的列表里去
  • 如果当前是,,视为分隔符,忽略
  • 如果当前是数字,则我们将这个数字看作一个单独的NestedInteger,将它的值算出来,并添加到栈顶NestedInteger的列表里去

栈中一开始是没有元素的,为了避免分类讨论栈是否为空,我们给栈内默认添加一个元素。

代码实现

public NestedInteger deserialize(String s) {
    Stack < NestedInteger > stack = new Stack < > ();
    stack.push(new NestedInteger());
    for (int i = 0; i < s.length();) {
        if (s.charAt(i) == ',') {
            i++;
            continue;
        } else if (s.charAt(i) == '[') {
            stack.push(new NestedInteger());
            i++;
        } else if (s.charAt(i) == ']') {
            NestedInteger top = stack.peek();
            stack.pop();
            stack.peek().add(top);
            i++;
        } else {
            int j = i;
            while (j < s.length() && (s.charAt(j) <= '9' && s.charAt(j) >= '0' || s.charAt(j) == '-')) j++;
            stack.peek().add(new NestedInteger(Integer.parseInt(s.substring(i, j))));
            i = j;
        }
    }

    return stack.peek().getList().get(0);
}

运行结果

Snipaste_2023-02-21_20-25-34.png

复杂度分析

  • 空间复杂度:O(1)O(1)
  • 时间复杂度:O(n)O(n)

掘金(JUEJIN)  一起分享知识, Keep Learning!