38. Count and Say*
https://leetcode.com/problems/count-and-say/
题目描述
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 where 1 ≤ n ≤ 30, generate the term of the count-and-say sequence. You can do so recursively, in other words from the previous member read off the digits, counting the number of digits in groups of the same digit.
Note: Each term of the sequence of integers will be represented as a string.
Example 1:
Input: 1
Output: "1"
Explanation: This is the base case.
Example 2:
Input: 4
Output: "1211"
Explanation: For n = 3 the term was "21" in which we have two groups "2" and "1", "2" can be read as "12" which means frequency = 1 and value = 2, the same way "1" is read as "11", so the answer is the concatenation of "12" and "11" which is "1211".
C++ 实现 1
给出第 6 个结果就知道题目啥意思了:
1. 1
2. 11
3. 21
4. 1211
5. 111221
6. 312211
发现用双指针就可以搞定, 计算 S[i, ..., j] 中的相同字符多少个. 下面是使用递归的做法.
class Solution {
public:
string countAndSay(int n) {
if (n == 1) return "1";
auto prev = countAndSay(n - 1);
string res;
for (int i = 0; i < prev.size(); ++ i) {
int j = i;
while (j + 1 < prev.size() && prev[j] == prev[j + 1]) ++ j;
auto count = j - i + 1;
res += std::to_string(count) + prev[i];
i = j;
}
return res;
}
};
C++ 实现 2
下面是使用迭代的做法:
class Solution {
public:
string countAndSay(int n) {
string prev = "1";
while (--n) {
string res = "";
for (int i = 0; i < prev.size();) {
int j = i;
while (j + 1 < prev.size() && prev[j + 1] == prev[i])
++ j;
res += to_string(j - i + 1) + prev[i];
i = j + 1;
}
prev = res;
}
return prev;
}
};
