1. 外观数列问题解析
"外观数列"(Count and Say)是力扣上一道经典的递归和字符串处理题目,编号第38题。这道题看似简单,却蕴含着递归思想和字符串处理的精髓,非常适合用来训练算法思维。
我第一次遇到这道题时,被它奇特的定义方式吸引了。题目描述是这样的:给定一个正整数n,输出外观数列的第n项。外观数列是一个由数字字符串组成的序列,其递归定义如下:
- countAndSay(1) = "1"
- countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串
举个例子,前几项的外观数列是这样的:
- "1" (第一项)
- "11"(描述前一项:一个1)
- "21"(描述前一项:两个1)
- "1211"(描述前一项:一个2,一个1)
- "111221"(描述前一项:一个1,一个2,两个1)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题理解与递归解法
2.1 递归思路分析
这道题最直观的解法就是递归。因为每一项都依赖于前一项的结果,这正符合递归"自相似"的特性。
递归解法可以分为两个主要部分:
- 基本情况:当n=1时,直接返回"1"
- 递归情况:对于n>1,先获取n-1项的结果,然后对这个结果进行"描述"
"描述"的过程实际上就是行程长度编码(Run-Length Encoding),即统计连续相同字符的个数和字符本身。例如:
- "1211"会被描述为"1个1,1个2,2个1" → "111221"
2.2 递归实现代码
以下是C++的递归实现示例:
cpp复制class Solution {
public:
string countAndSay(int n) {
if (n == 1) return "1";
string prev = countAndSay(n - 1);
string result;
int count = 1;
for (int i = 0; i < prev.size(); i++) {
if (i + 1 < prev.size() && prev[i] == prev[i + 1]) {
coun
