j

jaryue

V1

2023/05/05阅读:21主题:默认主题

leetcode 38. 外观数列

leetcode 38. 外观数列.


题目描述

  1. 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

countAndSay(1) = "1" countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。 前五项如下:

  1. 1
    
  2. 11
    
  3. 21
    
  4. 1211
    
  5. 111221
    

第一项是数字 1 描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11" 描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21" 描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211" 描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221" 要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

示例 1:

输入:n = 1 输出:"1" 解释:这是一个基本样例。 示例 2:

输入:n = 4 输出:"1211" 解释: countAndSay(1) = "1" countAndSay(2) = 读 "1" = 一 个 1 = "11" countAndSay(3) = 读 "11" = 二 个 1 = "21" countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"

提示:

1 <= n <= 30

解题思路

法1

方法1:动态规划\

  1. 与前一个有关的问题都可以使用动态规范的思想
  2. 第n行要描述n-1行的状态,而n-1行要描述n-2行的状态,那么我们可以从第一行开始描述储存上一次的结果给到下一次使用
  3. 1
    
  4. 11
    
  5. 21
    
  6. 1211
    
  7. 111221
    

..... 3. 最后得到第n行的结果

  • 时间复杂度(O(n^2))
  • 空间复杂度(O(1))

执行结果

法1

// 输出下一个描述
func nexts(s string) (r string) {
 j := 1//记录数字的个数
 for i := 1; i < len(s); i++ {//指针位置,用于判断两个是否相同
  if s[i-1] != s[i] {//不同则添加到返回值中
   r = r + fmt.Sprintf("%d%c", j, s[i-1])
   j = 1
  } else {//相同继续计数
   j++
  }
 }
 return r + fmt.Sprintf("%d%c", j, s[len(s)-1])//返回结果
}
func countAndSay(n int) (r string) {
 r = "1"//从1开始
 for i := 1; i < n; i++ {//使用动态规划储存返回结果并作为下一次输入
  r = nexts(r)
 }
 return
}

执行结果: 通过 显示详情 查看示例代码 添加备注

执行用时: 4 ms , 在所有 Go 提交中击败了 65.87% 的用户 内存消耗: 7.1 MB , 在所有 Go 提交中击败了 15.33% 的用户 通过测试用例: 30 / 30 炫耀一下:

分类:

后端

标签:

后端

作者介绍

j
jaryue
V1