Leetcode(38)-报数

报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 被读作  "one 1"  ("一个一") , 即 11
11 被读作 "two 1s" ("两个一"), 即 21
21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211

给定一个正整数 n ,输出报数序列的第 n 项。

注意:整数顺序将表示为一个字符串。

自己的思路:一开始看到这个题目,想着要把这个序列弄出来,然后根据输入的位数,输出相应位置的数字就好。而且还要计算每个数字中各位数字的个数,如果用int存储,肯定是极为不便的,势必要用string型来存储。那么是转为string型呢,还是一开始就直接用string型呢。肯定是后者要方便很多。

void helper(vector<string> &nums,int n)
{
    string x="1";
    nums.push_back(x);
    nums.push_back("11");
    for(int k=2;k<n;k++)
    {
        int count =1;
        string str;
        for(int i=1;i<nums[k-1].size();i++)
        {
            if(nums[k-1][i]==nums[k-1][i-1])
            {
                count++;
            }
            else
            {
                str=str+(char)(count+'0')+nums[k-1][i-1];
                count =1;
            }
            if(i==nums[k-1].size()-1)
            {
                str+=(count+'0');
                str+=nums[k-1][i];
            }
        }
        nums.push_back(str);
    }
}
string countAndSay(int n) 
{
    helper(nums,n);
    return nums[n-1];
}

我这里首先将前两个提前输入进去,而且利用了一个额外的函数,将这个序列的前n个数先搞出来,在上层函数直接按位置去取。

虽然思路还算过关,但实现方式过于繁琐了,所以就参考了大神的实现方式:

string countAndSay(int n)
{
    if(n==0) return "";
    if(n==1) return "1";
    string str = "11";
    for(int i=2;i < n;i++)
    {
        int count = 1;
        string temp ;
        for(int j=1; j <str.length();j++)
        {  
            if(str[j]==str[j-1])
                count++;
            else
            {
                temp+=('0'+count);
                temp+=str[j-1];
                count=1;
            }
            if(j==str.length()-1)
            {
                temp+=(count+'0');
                temp+=str[j];
            }
        }
        str = temp; 
    }
    return str;
}

思路和我类似,但他并没有把所有序列都得到,他只是去找目标位置的数字,这个是符合题意的,但是因为避免下面的访问越界,仍然要把前两个值提前固定。(暂时没想到其他的办法)

原文地址:https://www.cnblogs.com/mini-coconut/p/8981417.html