力扣385(java)-迷你语法分析器(中等)

题目:

给定一个字符串 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]

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/mini-parser
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

 最开始看到注解那么多,怕了~

 1 /**
 2  *// 这是允许创建嵌列表的接口
 3  * // This is the interface that allows for creating nested lists.
 4  * // 你不应该实现它,也不应该猜测它的实现
 5  * // You should not implement it, or speculate about its implementation
 6  * public interface NestedInteger {
 7  *     // Constructor initializes an empty nested list.
 8  *     public NestedInteger();( 构造函数初始化一个空的嵌套列表)
 9  *
10  *     // Constructor initializes a single integer.
11  *     public NestedInteger(int value);(构造函数初始化单个整数)
12  *
13  *     // @return true if this NestedInteger holds a single integer, rather than a nested list.(如果此NestedInteger包含单个整数,而不是嵌套列表,则返回True)
14  *     public boolean isInteger();
15  *
16  *     // @return the single integer that this NestedInteger holds, if it holds a single integer(如果NestedInteger包含单个整数,则返回此NestedInteger保存的单个整数)
17  *     // Return null if this NestedInteger holds a nested list(如果此NestedInteger包含嵌套列表,则返回NULL)
18  *     public Integer getInteger();
19  *
20  *     // Set this NestedInteger to hold a single integer.(将此NestedInteger设置为包含单个整数)
21  *     public void setInteger(int value);
22  *
23  *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.(设置此NestedInteger以保存嵌套列表并向其添加嵌套整数)
24  *     public void add(NestedInteger ni);
25  *
26  *     // @return the nested list that this NestedInteger holds, if it holds a nested list(如果NestedInteger包含嵌套列表,则返回此NestedInteger保存的嵌套列表)
27  *     // Return empty list if this NestedInteger holds a single integer(如果此NestedInteger包含单个整数,则返回空列表)
28  *     public List<NestedInteger> getList();
29  * }
30  */

使用栈来存储嵌套的对象,遍历字符串s,对遇到的字符进行分情况讨论:

  • 当字符串开头不是'['时,代表s是纯数字,将数字字符转换成整数返回即可;
  • 如果当前字符是'[',创建一个新NesteInteger对象,压入栈;
  • 如果当前字符是'-',则对负号进行标记;
  • 如果当前字符是数字,则取出连续的数字;
  • 如果当前字符是','或者']',如果这时前面一位为数字,就先判断前面这个数的正负(为负就加上负号),然后对栈顶对象通过add插入数字新生成的NestedInteger对象,重置num和标记位。如果当前栈不为空并且当前位']'(末尾是 ]] 这种情况时),就需要把当前栈顶元素弹出并保存,然后pop栈顶元素,通过add插入到现在的栈顶中。

最后输出栈顶元素就是答案。

代码:

 1 class Solution {
 2     public NestedInteger deserialize(String s) {
 3         //如果第一个字符不为'[',说明为一个整数
 4         if(s.charAt(0) != '['){
 5             return new NestedInteger(Integer.parseInt(s));
 6         }
 7         Deque<NestedInteger> stack = new ArrayDeque<NestedInteger>();
 8         //设置整数的初始值
 9         int num = 0;
10         //设置符号位初始值(正)
11         boolean sign = false;
12         for(int i = 0; i < s.length(); i++){
13             char c = s.charAt(i);
14             if(c == '['){
15                 //创建一个新的实例并压入栈中
16                 stack.addLast(new NestedInteger());
17             }else if(c == '-'){
18                 sign = true;
19             }else if(Character.isDigit(c)){
20                 num = num * 10 + c - '0';
21             }else if(c == ',' || c == ']'){
22                 //说明上一个数已经遍历完了
23                 if(Character.isDigit(s.charAt(i-1))){
24                     //如果存在前一个数为负数
25                     if(sign){
26                          num *= -1;
27                         }
28                 //对栈顶对象通过add插入生成数字子串的NestedInteger对象中
29                 stack.peekLast().add(new NestedInteger(num));
30                 }
31                 //重置num和sign
32                 num = 0;
33                 sign = false;
34                 //当栈中上一层有对象时
35                 if(c == ']' && stack.size() > 1){
36                //将栈顶的NestedInteger弹出后加入下一个NestedInteger对象,实现嵌套
37                     NestedInteger cur = stack.peekLast();
38                     stack.pollLast();
39                     stack.peekLast().add(cur);
40                 }     
41             }
42         }
43         return stack.pollLast();
44     }
45 }

posted on 2022-09-10 19:40  我不想一直当菜鸟  阅读(45)  评论(0编辑  收藏  举报