前言
在学习编程的过程中,算法题目是提升逻辑思维和编程能力的重要途径。最近,我在使用豆包MarsCode AI刷题时,遇到了一个关于数字翻译成字符串的题目。这个题目不仅考察了对动态规划的理解,还让我思考了如何将数字与字母之间的映射关系进行有效的计算。在这篇文章中,我将详细解析这个题目,包括解题思路、代码实现以及我的个人学习心得,希望能对正在学习的同学们有所帮助。
题目描述
题目要求我们将一个数字翻译成字符串,翻译规则是:0对应"a",1对应"b",依此类推直到25对应"z"。一个数字可能有多种翻译方法。我们的目标是计算一个数字有多少种不同的翻译方法。
示例
-
示例1:
- 输入:
num = 12258 - 输出:
5 - 解释:可以翻译为 "bccfi", "bwfi", "bczi", "mcfi" 和 "mzi"。
- 输入:
-
示例2:
- 输入:
num = 1400112 - 输出:
6
- 输入:
-
示例3:
- 输入:
num = 2110101 - 输出:
10
- 输入:
-
示例4:
- 输入:
num = 25 - 输出:
2
- 输入:
-
示例5:
- 输入:
num = 1023 - 输出:
4
- 输入:
解题思路
为了求解这个问题,我们可以使用动态规划的方法。动态规划是一种通过将问题分解为更小的子问题来解决复杂问题的有效策略。我们可以定义一个数组dp,其中dp[i]表示到达第i个数字时的翻译方法数量。
动态规划步骤
-
初始化:
- 将输入数字转换为字符串,获取其长度
n。 - 创建一个长度为
n+1的dp数组,初始值为1,dp[0]表示没有数字时的翻译方式数量为1。
- 将输入数字转换为字符串,获取其长度
-
状态转移:
- 对于每个数字
i(从1到n),我们需要判断当前数字和前一个数字的组合是否在10到25之间。 - 如果
num_str[i-1]不为0,dp[i]可以直接继承dp[i-1]的值。 - 如果
10 <= int(num_str[i-2:i]) <= 25,则可以通过dp[i-2]的值进行累加。
- 对于每个数字
-
返回结果:
- 最终返回
dp[n],即整个数字的翻译方法数量。
- 最终返回
代码实现
以下是实现上述思路的Python代码:
def solution(num):
num_str = str(num)
n = len(num_str)
if n == 0:
return 0
if n == 1:
return 1 if num_str[0] != '0' else 0
dp = [0] * (n + 1)
dp[0] = 1 # 空字符串的翻译方式
dp[1] = 1 if num_str[0] != '0' else 0 # 只有一个数字的翻译方式
for i in range(2, n + 1):
if num_str[i - 1] != '0':
dp[i] += dp[i - 1]
if 10 <= int(num_str[i - 2:i]) <= 25:
dp[i] += dp[i - 2]
return dp[n]
if __name__ == "__main__":
print(solution(12258) == 5)
print(solution(1400112) == 6)
print(solution(2110101) == 10)
print(solution(25) == 2)
print(solution(1023) == 4)
个人思考与总结
-
时间复杂度:
- 在代码实现中,主要循环是针对每个数字进行的,外层循环遍历从2到
n,因此时间复杂度为O(n)。
- 在代码实现中,主要循环是针对每个数字进行的,外层循环遍历从2到
-
空间复杂度:
- 空间复杂度主要由我们使用的
dp数组决定。我们创建了一个长度为n+1的数组来存储每个位置的翻译方法数量,因此空间复杂度为O(n)。
- 空间复杂度主要由我们使用的
-
学习反思:
- 在解决这个问题的过程中,我深刻体会到了动态规划的强大之处。通过将问题分解为更小的子问题,并利用之前的计算结果,我们能够有效地找到最优解。
- 通过使用豆包MarsCode AI刷题,我不仅提高了自己的编程能力,还加深了对动态规划的理解。每一次的错误和调试都是提升编程能力的机会,遇到难以解决的问题时,借助AI工具进行检查和调试,帮助我发现了逻辑漏洞并顺利优化了代码。
工具运用
通过这篇文章的分析与分享,希望能对正在使用豆包MarsCode AI刷题的同学们有所帮助,让我们一起在编程的道路上不断进步!动态规划的学习过程虽然艰难,但只要坚持不懈,定能掌握这一重要的算法思想。