LeetCode385. 迷你语法分析器(Mini P)

版权声明:转载请说明出处!!! https://blog.csdn.net/u012585868/article/details/84034937

题目描述

给定一个用字符串表示的整数的嵌套列表,实现一个解析它的语法分析器。
列表中的每个元素只可能是整数或整数嵌套列表
提示:
你可以假定这些字符串都是格式良好的:
字符串非空
字符串不包含空格
字符串只包含数字0-9 [ - , ]
示例 1:

给定 s = "324",
你应该返回一个 NestedInteger 对象,其中只包含整数值 324。

示例 2:

给定 s = "[123,[456,[789]]]",
返回一个 NestedInteger 对象包含一个有两个元素的嵌套列表:
1. 一个 integer 包含值 123
2. 一个包含两个元素的嵌套列表:
    i.  一个 integer 包含值 456
    ii. 一个包含一个元素的嵌套列表
         a. 一个 integer 包含值 789

再理题意:

  • 对于NestedInteger(),构造函数初始化一个空的嵌套列表。
  • 对于NestedInteger(int value),构造函数初始化一个整数。
  • 对于bool isInteger() const,如果此NestedInteger包含单个整数而不是嵌套列表,则返回true。
  • 对于int getInteger() const,返回此NestedInteger保存的单个整数(如果它包含单个整数),如果此NestedInteger包含嵌套列表,则结果未定义。
  • 对于void setInteger(int value),设置此NestedInteger以保存单个整数。
  • 对于void add(const NestedInteger &ni),设置此NestedInteger以保存嵌套列表并向其添加嵌套整数。
  • 对于const vector< NestedInteger> &getList() const,如果它拥有嵌套列表,则返回此NestedInteger包含的嵌套列表,如果此NestedInteger包含单个整数,则结果未定义。

递归解法思路:

  1. 首先判断s是否为空,为空直接返回;
  2. s不为空的话看首字符是否为’[’,不是的话说明s为一个整数,我们直接返回结果。
  3. 如果s中首字符是’[’,且s长度小于等于2,说明没有内容,直接返回结果。(’[‘或’[]’)
  4. 如果s长度大于2,我们从i=1开始遍历,我们需要一个变量start来记录某一层的真实位置,用cnt来记录跟真实位置是否为同一深度,cnt=0表示同一深度,由于中间每段都是由逗号隔开,所以当我们判断当cnt为0,且当前字符是逗号或者已经到字符串末尾了,我们把start到当前位置之间的字符串取出来递归调用函数,把返回结果加入res中,然后start更新为i+1。如果遇到’[’,计数器cnt自增1,若遇到’]’,计数器cnt自减1。
    递归解法代码:
/**
 * // 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;如果此NestedInteger包含单个整数而不是嵌套列表,则返回true。
 *
 *     // 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;返回此NestedInteger保存的单个整数(如果它包含单个整数),如果此NestedInteger包含嵌套列表,则结果未定义。
 *
 *     // Set this NestedInteger to hold a single integer.
 *     void setInteger(int value);设置此NestedInteger以保存单个整数。
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     void add(const NestedInteger &ni);设置此NestedInteger以保存嵌套列表并向其添加嵌套整数。
 *
 *     // 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;如果它拥有嵌套列表,则返回此NestedInteger包含的嵌套列表,如果此NestedInteger包含单个整数,则结果未定义。
 * };
 */
class Solution {
public:
    NestedInteger deserialize(string s) {
        if(s.empty()) return NestedInteger();
        if(s[0]!='[')  return NestedInteger(stoi(s));
        if(s.size()<=2) return NestedInteger();
        NestedInteger res;
        int start=1,cnt=0;
        for (int i=1;i<s.size();i++){
            if(cnt==0&&(s[i]==','||i==s.size()-1)){
                res.add(deserialize(s.substr(start,i-start)));
                start=i+1;
            } 
            else if(s[i]=='[') cnt++;
            else if(s[i]==']') cnt--;
        }
        return res;
    }
};

非递归解法思路:
使用迭代的方法来做,需要使用栈来辅助,用变量start记录起始位置,我们遍历字符串,如果遇到’[’,我们给栈中加上一个空的NestInteger,如果遇到的字符数逗号或者’]’,如果i>start,那么我们给栈顶元素调用add来新加一个NestInteger,初始化参数传入start到i之间的子字符串转为的整数,然后更新start=i+1,当遇到的’]'时,如果此时栈中元素多于1个,那么我们将栈顶元素取出,通过调用add函数加入新的栈顶元素中以实现嵌套。
非递归解法代码:

/**
 * // 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;如果此NestedInteger包含单个整数而不是嵌套列表,则返回true。
 *
 *     // 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;返回此NestedInteger保存的单个整数(如果它包含单个整数),如果此NestedInteger包含嵌套列表,则结果未定义。
 *
 *     // Set this NestedInteger to hold a single integer.
 *     void setInteger(int value);设置此NestedInteger以保存单个整数。
 *
 *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
 *     void add(const NestedInteger &ni);设置此NestedInteger以保存嵌套列表并向其添加嵌套整数。
 *
 *     // 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;如果它拥有嵌套列表,则返回此NestedInteger包含的嵌套列表,如果此NestedInteger包含单个整数,则结果未定义。
 * };
 */
class Solution {
public:
    NestedInteger deserialize(string s) {
        if(s.empty()) return NestedInteger();
        if(s[0]!='[') return NestedInteger(stoi(s));
        stack<NestedInteger> res;
        int start=1;
        for(int i=0;i<s.size();i++){
            if(s[i]=='[') {
                res.push(NestedInteger());
                start=i+1;
            }
            else if(s[i]==','||s[i]==']'){
                if(i>start) res.top().add(stoi(s.substr(start,i-start)));
                start=i+1;
                if(s[i]==']') {
                    if(res.size()>1) {
                        NestedInteger temp=res.top();res.pop();
                        res.top().add(temp);
                    }
                }
            }
        }
        return res.top();
    }
};

猜你喜欢

转载自blog.csdn.net/u012585868/article/details/84034937
今日推荐