欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 38. 外观数列

38. 外观数列

2025/2/24 13:09:43 来源:https://blog.csdn.net/qq_35085273/article/details/139901687  浏览:    关键词:38. 外观数列

题目

「外观数列」是一个数位字符串序列,由递归公式定义:

countAndSay(1) = "1"
countAndSay(n)countAndSay(n-1) 的行程长度编码。

行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 “3322251”,我们将 “33” 用 “23” 替换,将 “222” 用 “32” 替换,将 “5” 用 “15” 替换并将 “1” 用 “11” 替换。因此压缩后字符串变为 “23321511”。

给定一个整数 n,返回外观数列的第 n 个元素。

示例 1:

输入:n = 4
输出:“1211”

解释:

countAndSay(1) = "1"
countAndSay(2) = "1" 的行程长度编码 = “11”
countAndSay(3) = "11" 的行程长度编码 = “21”
countAndSay(4) = "21" 的行程长度编码 = “1211”

示例 2:

输入:n = 1
输出:“1”

解释:

这是基本情况。

提示:

1 <= n <= 30

代码

完整代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>char* countAndSay(int n) {char* result = NULL;char* origin = NULL;if (n == 1) {return strdup("1");} else {origin = (char*)calloc(5000, sizeof(char));result = (char*)calloc(5000, sizeof(char));char nums[] = "0123456789";strcpy(result, "1");for (int i = 1; i < n; i++) {strcpy(origin, result);strcpy(result, "");int lastNum = origin[0] - '0';int lastNumCnt = 1;char new[4] = {'\0'};for (int j = 1; j < strlen(origin); j++) {if (nums[lastNum] != origin[j]) {sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);lastNum = origin[j] - '0';lastNumCnt = 1;} else {lastNumCnt++;}}sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);}}free(origin);return result;
}

思路分析

这套代码用了字符串遍历和拼接的方法。

  • 首先,初始化基础情况,即当 n 为 1 时,直接返回 “1”。
  • 从第 2 个序列开始,每次根据前一个序列进行行程长度编码。
  • 使用两个字符串 originresult 来存储和构造新的序列。
  • 通过遍历 origin,计算每个字符的重复次数,并将其转换为新的子序列,最终拼接到 result 中。
  • 重复上述过程,直到生成第 n 个序列。

拆解分析

  1. 初始化和基础情况处理
if (n == 1) {return strdup("1");
}

当 n 为 1 时,直接返回 “1”。

  1. 初始化两个字符串 originresult
origin = (char*)calloc(5000, sizeof(char));
result = (char*)calloc(5000, sizeof(char));
strcpy(result, "1");

初始化两个字符串,用于存储和构造新的序列。

  1. 生成新的序列
for (int i = 1; i < n; i++) {strcpy(origin, result);strcpy(result, "");int lastNum = origin[0] - '0';int lastNumCnt = 1;char new[4] = {'\0'};for (int j = 1; j < strlen(origin); j++) {if (nums[lastNum] != origin[j]) {sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);lastNum = origin[j] - '0';lastNumCnt = 1;} else {lastNumCnt++;}}sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);
}

遍历 origin,计算每个字符的重复次数,并将其转换为新的子序列,最终拼接到 result 中。

复杂度分析

  • 时间复杂度:O(n * m),其中 n 为输入整数,m 为每个生成序列的长度。每次生成新的序列需要遍历前一个序列的所有字符。
  • 空间复杂度:O(m),用于存储生成的序列。

一题多解

方法2:使用递归的方式

完整代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>char nums[] = "0123456789";char* nextRLE(char* s) {char* result = (char*)calloc(5000, sizeof(char));int lastNum = s[0] - '0';int lastNumCnt = 1;char new[4] = {'\0'};for (int j = 1; j < strlen(s); j++) {if (nums[lastNum] != s[j]) {sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);lastNum = s[j] - '0';lastNumCnt = 1;} else {lastNumCnt++;}}sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);free(s);return result;
}char* countAndSay(int n) {char* result = strdup("1");if (n == 1) {return result;} else {for (int i = 1; i < n; i++) {result = nextRLE(result);}}return result;
}

思路分析

这套代码用了递归和字符串拼接的方法。

  • 定义一个辅助函数 nextRLE,用于生成给定字符串的下一个行程长度编码字符串。
  • countAndSay 函数中,从 “1” 开始,逐步调用 nextRLE,直到生成第 n 个序列。

拆解分析

  1. nextRLE函数
char* nextRLE(char* s) {char* result = (char*)calloc(5000, sizeof(char));int lastNum = s[0] - '0';int lastNumCnt = 1;char new[4] = {'\0'};for (int j = 1; j < strlen(s); j++) {if (nums[lastNum] != s[j]) {sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);lastNum = s[j] - '0';lastNumCnt = 1;} else {lastNumCnt++;}}sprintf(new, "%d%d", lastNumCnt, lastNum);strcat(result, new);free(s);return result;
}

生成给定字符串的下一个行程长度编码字符串。

  1. countAndSay函数
char* countAndSay(int n) {char* result = strdup("1");if (n == 1) {return result;} else {for (int i = 1; i < n; i++) {result = nextRLE(result);}}return result;
}

逐步调用 nextRLE 函数,直到生成第 n 个序列。

复杂度分析

  • 时间复杂度:O(n * m),其中 n 为输入整数,m 为每个生成序列的长度。
  • 空间复杂度:O(m),用于存储生成的序列。

结果

正常

在这里插入图片描述

递归

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词