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"
or 11
.11
is read off as "two 1s"
or 21
.21
is read off as "one 2
, then one 1"
or 1211
.
Given an integer n, 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",根据以下规则生成字符串。如果一个字符s[i]与s[i-1]和s[i+1]不同,那么就生成"1"+s[i]的字符串;如果连续n个字符都相同,那么就生成"n"+s[i]的字符串。例如字符串"1"会生成"11",而"11"会生成"21","21"又会生成"1211",以此类推。
解题思路:有递归和非递归两种解法,核心思路是一样的,只是实现方式不同。每一次生成的字符串都作为下一次的输入,直到生成第n个字符串为止。
代码如下:
//C++实现
class Solution {
public:
string countAndSay(int n) {
return countAndSay("1", 1, n);
// return _countAndSay(n);
}
private:
//递归版本
string countAndSay(string s, int depth, int n) {
if(depth == n) return s;
string ans;
int cnt = 1;
for(int i = 0;i < s.length();i++){
if(s[i] == s[i + 1]){
cnt++;
}
else {
ans += cnt + '0';
ans += s[i];
cnt = 1;
}
}
return countAndSay(ans, depth + 1, n);
}
//非递归版本
string _countAndSay(int n) {
string tmp = "1";
string ans;
int cnt = 1;
for(int i = 2;i <= n;i++){
for(int j = 0;j < tmp.length();j++){
if(tmp[j] == tmp[j + 1]){
cnt++;
}
else {
ans += cnt + '0';
ans += tmp[j];
cnt = 1;
}
}
tmp = ans;
ans = "";
}
return tmp;
}
};
//C语言实现
#define maxn 10005
char s[maxn], t[maxn];
char* countAndSay(int n) {
strcpy(s, "1");
strcpy(t, "");
int cnt = 1;
char tmp[3];
for(int i = 2;i <= n;i++){
int len = strlen(s);
for(int j = 0;j < len;j++){
if(s[j] == s[j + 1]){
cnt++;
}else {
tmp[0] = cnt + '0';
tmp[1] = s[j];
tmp[2] = '\0';
strcat(t, tmp);
cnt = 1;
}
}
strcpy(s, t);
strcpy(t, "");
}
return s;
}