各位题友大家好,@负雪明烛 又出现了。
题意
取值为 n 的「外观数列」是对取值为 n - 1 的「外观数列」的描述。
解题思路
解法一:循环
两重循环的思路是:
- 外层循环 $i$ 负责递增 $1 .. n$;
- 内存循环负责求当取值为 $i$ 时的外观数列。
Java 和 Python 代码如下:
public class Solution {
public String countAndSay(int n) {
StringBuilder ans = new StringBuilder("1");
StringBuilder prev;
int count;
char say;
for(int i = 1; i < n; i++){
prev = ans;
ans = new StringBuilder();
count = 1;
say = prev.charAt(0);
for(int j = 1; j < prev.length(); j++){
if(say != prev.charAt(j)){
ans.append(count).append(say);
count = 1;
say = prev.charAt(j);
}else{
count++;
}
}
ans.append(count).append(say);
}
return ans.toString();
}
}
class Solution(object):
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
res = "1"
for i in range(n - 1):
prev = res[0]
count = 1
ans = ""
for j in range(1, len(res)):
cur = res[j]
if prev != cur:
ans = ans + str(count) + str(prev)
prev = cur
count = 0
count += 1
res = ans + str(count) + str(prev)
return res
- 时间复杂度:$O(n * m)$,$n$ 是输入的数字,$m$ 是「外观数列」的最大长度;
- 空间复杂度:$O(m)$。
解法二:递归
其实,按照题目描述的话,我们最容易想到的应该就是递归解法。
题目描述是:
- countAndSay(1) = “1”
- countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
这个意思就是想求 countAndSay(n) 的话,必须先求 countAndSay(n-1),这就是标准的递归。
使用递归求解,一定不要用大脑去模拟递归的过程。大脑能压几个栈?
正确的做法是:记住递归函数的定义。比如本题中的递归函数 countAndSay(int n)
含义是当取值为 $n$ 时的外观数列。
那么,必须先求出取值为 $n - 1$ 时的外观数列,怎么求?根据递归函数的定义,就是 countAndSay(n - 1)
。至于 countAndSay(n - 1)
怎么算的,我们不用管。只要知道这个函数能给我们正确的结果就行。
我在下面的代码把 countAndSay(n - 1)
的结果即为 before,然后统计了 before 中各个数字出现的次数,就是取值为 $n$ 时的外观数列。
C++ 代码如下:
class Solution {
public:
string countAndSay(int n) {
if (n == 1) {
return "1";
}
string before = countAndSay(n - 1);
string res;
char cur = before[0];
int count = 1;
for (int i = 1; i < before.size(); ++i) {
if (before[i] != cur) {
res += to_string(count) + cur;
cur = before[i];
count = 0;
}
count ++;
}
res += to_string(count) + cur;
return res;
}
};
- 时间复杂度:$O(n * m)$,$n$ 是输入的数字,$m$ 是「外观数列」的最大长度;
-
刷题心得
递归是最贴合本题意的解法。
- 递归的时间复杂度和遍历是一样的,因为 $1..n$ 中的每个数字都被计算了一次。
OK,以上就是 @负雪明烛 写的今天题解的全部内容了,如果你觉得有帮助的话,求赞、求关注、求收藏。如果有疑问的话,请在下面评论,我会及时解答。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
祝大家 AC 多多,Offer 多多!我们下期再见!