跳到主要内容

38-外观数列

题目

leetcode 38-外观数列 给定一个正整数 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" 的描述如下图:

img

这题题目有点绕,其实就是说,第一项是 1,第二项是 1 个 1,第三项是 2 个 1,第四项是 1 个 2 1 个 1,第五项是 1 个 1 1 个 2 2 个 1,以此类推

整体的思路就是递归

/*
* @lc app=leetcode.cn id=38 lang=golang
*
* [38] 外观数列
*/

import "strconv"

// @lc code=start
func countAndSay(n int) string {
// 递归
if n == 1 {
return "1"
}

// 获取上一层的字符串
prev := countAndSay(n - 1)
// 定义结果字符串
res := ""
// 定义左右指针
left, right := 0, 0
// 遍历字符串
for right < len(prev) {
// 统计相同字符的个数
for right < len(prev) && prev[left] == prev[right] {
right++
}
// 拼接字符串
res += strconv.Itoa(right - left)
res += string(prev[left])
// 移动左指针
left = right
}

return res
}

// @lc code=end