• 作者: 负雪明烛
  • id: fuxuemingzhu
  • 公众号:负雪明烛
  • 本文关键词:LeetCode,力扣,算法,算法题,外观数列,Count and Say,刷题群

题目地址:https://leetcode.com/problems/count-and-say/#/description

题目描述

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 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"

题目大意

统计连续字符出现的次数,说出这个字符是什么。把一个串就这么统计并且说出来。现在要知道第n个串说出来。

解题方法

解法一:循环

两重循环的思路是:

  • 外层循环

    i

    i

    i 负责递增

    1..

    n

    1 .. n

    1..n;

  • 内存循环负责求当取值为

    i

    i

    i 时的外观数列。

Java 代码如下:

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();
}
}

python 代码如下:

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

    )

    O(n * m)

    O(n∗m),

    n

    n

    n 是输入的数字,

    m

    m

    m 是「外观数列」的最大长度;

  • 空间复杂度:

    O

    (

    m

    )

    O(m)

    O(m)。

解法二:递归

其实,按照题目描述的话,我们最容易想到的应该就是递归解法。

题目描述是:

  • countAndSay(1) = "1"
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

这个意思就是想求 countAndSay(n) 的话,必须先求 countAndSay(n-1),这就是标准的递归。

使用递归求解,一定不要用大脑去模拟递归的过程。大脑能压几个栈?

正确的做法是:记住递归函数的定义。比如本题中的递归函数 countAndSay(int n)含义是当取值为

n

n

n 时的外观数列。

那么,必须先求出取值为

n

1

n - 1

n−1 时的外观数列,怎么求?根据递归函数的定义,就是 countAndSay(n - 1)。至于 countAndSay(n - 1) 怎么算的,我们不用管。只要知道这个函数能给我们正确的结果就行。

我在下面的代码把 countAndSay(n - 1) 的结果即为 before,然后统计了 before 中各个数字出现的次数,就是取值为

n

n

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

    )

    O(n * m)

    O(n∗m),

    n

    n

    n 是输入的数字,

    m

    m

    m 是「外观数列」的最大长度;

  • 空间复杂度:

    O

    (

    m

    )

    O(m)

    O(m)。

刷题心得

  • 递归是最贴合本题意的解法。
  • 递归的时间复杂度和遍历是一样的,因为

    1..

    n

    1..n

    1..n 中的每个数字都被计算了一次。

日期

2017 年 5 月 11 日
2018 年 11 月 22 日 —— 感恩节快乐~
2021 年 10 月 15 日

【LeetCode】38. 外观数列 Count and Say的更多相关文章

  1. Java实现 LeetCode 38 外观数列

    38. 外观数列 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述.前五项如下: 1 11 21 1211 111221 1 被读作 "one 1" ...

  2. PAT 1084 外观数列(20)(代码+思路+推荐测试用例)

    1084 外观数列(20 分) 外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ... 它从不等于 1 的数字 d 开始,序列的第 ...

  3. 1084 外观数列 (20 分)C语言

    外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ... 它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述. ...

  4. P1084 外观数列

    转跳点:

  5. PAT 1084 外观数列

    https://pintia.cn/problem-sets/994805260223102976/problems/994805260583813120 外观数列是指具有以下特点的整数序列: d, ...

  6. PAT(B) 1084 外观数列(Java)

    题目链接:1084 外观数列 (20 point(s)) 题目描述 外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, - 它从不等于 ...

  7. PAT Basic 1084 外观数列 (20 分)

    外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ... 它从不等于 1 的数字 d 开始,序列的第 n+1 项是对第 n 项的描述. ...

  8. look and say 外观数列的python实现

    #look_and_say 外观数列 如果我们把 1 作为Look-and-say 数列的第一项,那么,它的前几项是这样的: 1, 11, 21, 1211, 111221, 312211, 1311 ...

  9. PAT乙级:1084 外观数列 (20分)

    PAT乙级:1084 外观数列 (20分) 题干 外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ... 它从不等于 1 的数字 d ...

随机推荐

  1. C7的开机自启动设置

    CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分 系统服务放在/usr/lib/systemd/system [Un ...

  2. JavaScript | 新手村(一)变量,运算和变量方法

    资料来自:JavaScript 第一步 1. 向 html 页面添加 JavaScript 1.1 内部 JavaScript 在 html 文件中的 </body> 标签前插入代码: & ...

  3. Shell 格式化输出printf、awk

    目录 Shell 文件的格式化与相关处理 printf.awk 格式化打印printf 案例.格式化输出文件内容 输出命令echo 案例 awk数据处理工具 语法格式 处理流程 AWK内置变量 条件 ...

  4. 生产调优2 HDFS-集群压测

    目录 2 HDFS-集群压测 2.1 测试HDFS写性能 测试1 限制网络 1 向HDFS集群写10个128M的文件 测试结果分析 测试2 不限制网络 1 向HDFS集群写10个128M的文件 2 测 ...

  5. 【区间dp】- P1880 [NOI1995] 石子合并

    记录一下第一道ac的区间dp 题目:P1880 [NOI1995] 石子合并 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码: #include <iostream> ...

  6. deque、queue和stack深度探索(下)

    deque如何模拟连续空间?通过源码可以看到这个模型就是通过迭代器来完成. 迭代器通过重载操作符+,-,++,--,*和->来实现deque连续的假象,如上图中的 finish-start ,它 ...

  7. [学习总结]7、Android AsyncTask完全解析,带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴 ...

  8. GO 数字运算

    大整数运算 // bigint project main.go package main import ( "fmt" "math" "math/bi ...

  9. 一个统计 CPU 内存 硬盘 使用率的shell脚本

    一个统计 CPU 内存 硬盘 使用率的shell脚本,供大家学习参考 #!/bin/bash #This script is use for describle CPU Hard Memery Uti ...

  10. SSO(单点登录)示例

    此文为转载文章,出处:https://www.cnblogs.com/jpfss/p/9273680.html SSO在我们的应用中非常常见,例如我们在OA系统登录了,我们就可以直接进入采购系统,不需 ...