题目看起来非常的奇怪,点踩的人也非常的多。先看题目的描述:
The count-and-say sequence is the sequence of integers with the first five terms as following:
1. 1 2. 11 3. 21 4. 1211 5. 111221
1
is read off as"one 1"
or11
.11
is read off as"two 1s"
or21
.21
is read off as"one 2
, thenone 1"
or1211
.Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.
Note: Each term of the sequence of integers will be represented as a string.
Example 1:
Input: 1 Output: "1"
Example 2:
Input: 4 Output: "1211"
总之,输入 1 对应的字符串输出为 “1”,当输入 2 时,输出的的字符串是读 “1” 得到的字符串 “11”,即1个1,输入 3 时,输出的字符串是读上个输入 2 得到的字符串“11”得到的结果 “21”即2个1,依次类推,所以要得到一个输入对应输出的字符串,必须要得到从1开始的所有对应输出字符串才行。
下面的代码虽然复杂,但是比较容易理解,要考虑输入1和输入2的特殊情况,以及读的字符串的str1[i] ,str[i + 1]到字符串尾的情况,以及将数字转化为字符串的方式,string.push_back(char ch),可以在字符串尾添加单个字符,+=则可以添加字符串,初始化最好用string str = ""; 的形式来写,reverse(str.begin(), str.end());实现了字符串的翻转,reverse同时可以处理一般数组,reverse(a, a+4),4是长度;+ ‘0’ 实现将数字转化为单个字符,这些都要注意。
代码为:
class Solution {
public:
string countAndSay(int n) {
string ans;
if(n == 1)
{
ans = "1";
return ans;
}
if(n == 2)
{
ans = "11";
return ans;
}
int newP = 0;
string str1 = "11";
string str2 = "";
for(int j = 3; j <= n; j++)
{
str2.clear();
for(int i = 0; i < str1.size(); )
{
int cnt = 1;
if(newP == str1.size() - 1 && newP != 0 && str1[newP] != str1[newP - 1])
{
str2.push_back('1');
char ch = str1[newP];
str2.push_back(ch);
break;
}
while(str1[newP] == str1[newP + 1] && newP < str1.size() - 1)
{
newP += 1;
cnt++;
}
str2 += change(cnt);
char ch = str1[newP];
str2.push_back(ch);
newP += 1;
i = newP;
}
str1 = str2;
newP = 0;
}
ans = str1;
return ans;
}
string change(int a)
{
string res = "";
char ch;
while(a != 0)
{
ch = a % 10 + '0';
res.push_back(ch);
a /= 10;
}
reverse(res.begin(), res.end());
return res;
}
};