LeetCode第 38 题:外观数列(C++)

38. 外观数列 - 力扣(LeetCode)

每一个数字 n 对应的string都是完全由数字 n-1对应的string决定的,也就是1->2,2->3,3->4…
依次递推的。

递推的规则可以这么描述:

假设数字 n-1 对应的字符串 s已知,那么对s中的字符,从左到右-可以划分为多个区间(每个区间的元素都是一样的),比如 "11221"可以分为三部分 “111221”,每部分的特点可以用两个变量描述:num记录该部分的数字是多少,count记录数字的个数是多少。
那么,该部分映射到数字 n 对应的字符串就是 “count”+“num”。

至于处理方式,可以处理字符串或者数组,也可以转为数字处理,但是数字会面临溢出的问题。

用数组处理的好处是可以直接处理int型数字,最后转化为string返回即可,而且并不需要n个数组分别保存从1到n的结果值,我们可以使用滚动数组,因为计算n只需要知道n-1就行,两个数组即可。

class Solution {
public:
    string countAndSay(int n) {
        string res("");
        vector<vector<int>> a{{1}, {}};//第一项一个1,第二项先初始化为0
        int cur = 0, pre = 1-cur;
        for(int i = 2; i <= n; ++i){
            cur = i%2;
            pre = 1-cur;
            for(int j = 0; j < a[cur].size();){
                int num = a[cur][j];
                int count = 1;
                while(j+1 < a[cur].size() && a[cur][j+1] == num){
                    ++count;
                    ++j;
                }
                a[pre].push_back(count);
                a[pre].push_back(num); 
                ++j;
            }
            a[cur].clear();
        }
        for(const auto &c : a[(n-1)%2])   res += to_string(c);
        return res;
    }
};

不过写完感觉不用数组,直接处理字符串好像也差不多:

class Solution {
public:
    string countAndSay(int n) {
        string s1("1"), s2("");//第一项一个1
        for(int i = 2; i <= n; ++i){
            for(int j = 0; j < s1.size();){
                char num = s1[j];
                int count = 1;
                while(j+1 < s1.size() && s1[j+1] == num){
                    ++count;
                    ++j;
                }
                s2 += to_string(count);
                s2 += num;
                ++j;
            }
            s1.clear();
            s1 = s2;
            s2.clear();
        }
        return s1;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_32523711/article/details/107787756