20220415力扣每日一题

问题描述

385. 迷你语法分析器

给定一个字符串 s 表示一个整数嵌套列表,实现一个解析它的语法分析器并返回解析的结果 NestedInteger

列表中的每个元素只可能是整数或整数嵌套列表。

示例:

输入: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

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

思路

基本想法

        观察示例输入,发现输入的字符串可以粗分类为:①.纯整数(正负数均可),②.' [ ' 开头的合法的整数列表(含嵌套)。对于第①种输入,直接进行字符串转整数的函数操作即可(string里有现成的stoi()函数来进行此步操作),对于第②种输入,基本思想是先根据括号匹配的思路,将每个' [ '' ] ' 压栈弹栈,进而得到最终输出。对于中间出现的数字字符子串,则可以直接获取这些数字字符对应的整数压入当前栈顶进行处理。该题本质上就是反序列化,也即将字符串等数据转化为程序可处理的对象或变量,所以在题目给的编写样板里函数的名字为deserialize

示例过程可视化演示

 其中:①③⑤为识别到 '[' :需要将新的空列表压栈,②④⑥为识别到数字相关符号('0''9''-'):需要将数字字符相关的内容转换为整数类型添加在当前栈顶的列表中,⑦⑧⑨为识别到']':需要记录当前栈顶的列表弹栈,如果栈中还有未弹出的列表加入更新后的栈顶列表中。

        实际上在上述图例中,此问题的基本解决思路已经一目了然了,只需再考虑对应的一些边界条件处理就能真正解决此问题了。边界条件是当栈彻底清空时,此时弹出的元素就是我们需要的最终列表,可以使用一个NestedInterger来存储该列表并返回,这样得到的自然就是最终答案。

完整代码(C++)

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * class NestedInteger {
 *   public:
 *     // Constructor initializes an empty nested list.
 *     NestedInteger();
 *
 *     // Constructor initializes a single integer.
 *     NestedInteger(int value);
 *
 *     // Return true if this NestedInteger holds a single integer, rather than a nested list.
 *     bool isInteger() const;
 *
 *     // Return the single integer that this NestedInteger holds, if it holds a single integer
 *     // The result is undefined if this NestedInteger holds a nested list
 *     int getInteger() const;
 *
 *     // Set this NestedInteger to hold a single integer.
 *     void setInteger(int value);
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     void add(const NestedInteger &ni);
 *
 *     // Return the nested list that this NestedInteger holds, if it holds a nested list
 *     // The result is undefined if this NestedInteger holds a single integer
 *     const vector<NestedInteger> &getList() const;
 * };
 */
class Solution {
private:
    int getInt(string &s, int &index) { //数字字符转整数的实现函数
        int sz = s.size();
        bool negFlag = false; // flag of the number (sgn(x))
        int val = 0;
        if(s[index] == '-') {
            negFlag = true;
            index++;
        }
        while(index < sz && s[index] >= '0' && s[index] <= '9') {
            val = val * 10 + s[index] - '0';
            index++;
        }
        return negFlag ? -val : val;
    }
public:
    NestedInteger deserialize(string s) {
        if(*s.begin() != '[') { //数字或负号开头的字符串直接转化为整型变量
            return NestedInteger(stoi(s));
        }
        deque<NestedInteger> stk;
        int num = 0; //数字字符转整数的中间变量
        int index = 0; //当前的字符串指针指向点,初始时指向字符串头部(0)处
        //bool flag = false;
        NestedInteger res = NULL; //res记录最终需要的结果
        while(index < s.size()) {
            if(s[index] == '[') { //'['表示需要在栈顶添加新列表
                stk.push_front(NestedInteger());
                index++;
            } else if(s[index] == '-' || (s[index] >= '0' && s[index] <= '9')) {
                num = getInt(s, index); //获取当前数字字符序列对应的整数
                stk.front().add(NestedInteger(num)); //当前栈顶的列表加入刚转化的整数
            } else if(s[index] == ',') {
                index++; //','仅做分割符使用
            } else if(s[index] == ']') { //']'表示需要弹栈
                res = stk.front();//记录栈顶元素,防止弹栈后栈为空无法保存结果
                stk.pop_front();
                if(stk.empty()) //弹栈后发现栈为空,如果不加入新列表,临时结果无法存储进栈
                    stk.push_front(NestedInteger());
                stk.front().add(res);
                index++;
            }
        }
        /* 此处为for循环写法,并且在这块部分中,getInt()函数不封装
        for(int i = 0; i < s.size(); i++) {
            if(s[i] == '[') {
                stk.push_front(NestedInteger());
            }
            if(s[i] == '-') {
                flag = true;
            }
            if(s[i] >= '0' && s[i] <= '9') {
                num = num * 10 + s[i] - '0';
            }
            if(s[i] == ',' || s[i] == ']') {
                if(s[i - 1] >= '0' && s[i - 1] <= '9') {
                    if(flag) {
                        num *= -1;
                    }
                    stk.front().add(NestedInteger(num));
                }
                num = 0;
                flag = false;
                if(s[i] == ']' && stk.size() > 1) {
                    NestedInteger ni = stk.front();
                    stk.pop_front();
                    stk.front().add(ni);
                }
            }
        }
        return stk.front();
        */
        return res;
    }
};

最终结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值