迷你语法分析器

112 阅读3分钟

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

一、题目

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 <= 5 * 104
s 由数字、方括号 "[]"、负号 '-' 、逗号 ','组成
用例保证 s 是可解析的 NestedInteger
输入中的所有值的范围是 [-106, 106]

二、题解

主要是将字符串中提取出数字出来,如果字符串只包含数字那么就返回一个只有一个数字的对象,否则如果存在[]包含的数字,代表有嵌套数字,就需要返回对于的嵌套对象。

方法一

根据题意可知s 由数字、方括号 "[]"、负号 '-' 、逗号 ','组成,那么题目中所给的字符串s的第一个字符就可能为[或者-或者数字。那么我们可以先判断第一个字符,如果是[那么说明这个字符串有嵌套的列表数字,需要返回嵌套列表的NestedInteger对象;否则就只有一个数字,返回一个NestedInteger对象即可。因此我们需要递归遍历字符串s,因为字符串可能存在多重嵌套。具体的在遍历字符串s的时候,如果遍历的当前字符为[说明当前存在一个嵌套列表,我们就需要将嵌套的数字去递归处理,直到遇到]字符为一个嵌套,如果最后的一个非数字字符是,那么说明还存在其他嵌套列表,也还需要继续处理。如果遍历的当前字符不是[那么就需要解析处理数字,首先需要判断这个数字是不是负数的,那么就是判断第一个字符是不是-负号开头,然后我们就接着处理之后的数字用一个遍历累加起来,直到遇到非数字字符或者超出字符串长度为止,最后如果是有负号就需要将数字整成负数,最后返回一个NestedInteger对象即可。

三、代码

方法一 Java代码

class Solution {
    int index = 0;

    public NestedInteger deserialize(String s) {
        if (s.charAt(index) == '[') {
            index++;
            NestedInteger ni = new NestedInteger();
            while (s.charAt(index) != ']') {
                ni.add(deserialize(s));
                if (s.charAt(index) == ',') {
                    index++;
                }
            }
            index++;
            return ni;
        } else {
            int num = 0;
            while (index < s.length() && Character.isDigit(s.charAt(index))) {
                num = num * 10 + s.charAt(index) - '0';
                index++;
            }
            if (s.charAt(0)== '-') {
                num = -num;
            }
            return new NestedInteger(num);
        }
    }
}

时间复杂度:O(n),需要遍历一遍字符串的每一个字符。

空间复杂度:O(n),需要新建NestedInteger返回的对象以及栈空间。