报数序列是指一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
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; }
思路和我类似,但他并没有把所有序列都得到,他只是去找目标位置的数字,这个是符合题意的,但是因为避免下面的访问越界,仍然要把前两个值提前固定。(暂时没想到其他的办法)