算法的学习笔记—把数字翻译成字符串
【摘要】 在日常生活中,我们经常会遇到各种编码和解码的问题。今天,我们将讨论一个有趣的问题:如何将一串数字翻译成字母,并计算出有多少种不同的翻译方法。
😀前言
在日常生活中,我们经常会遇到各种编码和解码的问题。今天,我们将讨论一个有趣的问题:如何将一串数字翻译成字母,并计算出有多少种不同的翻译方法。
💝把数字翻译成字符串
💞问题描述
给定一个由数字组成的字符串,我们需要按照以下规则将其翻译成字母:
- 数字1-26分别对应字母a-z,例如1对应a,2对应b,…,26对应z。
- 例如,对于输入“12258”,它可以被翻译为以下几种不同的字符串:
- “abbeh”
- “lbeh”
- “aveh”
- “abyh”
- “lyh”
总共有5种不同的翻译方式。我们的任务是实现一个函数来计算一个数字字符串有多少种不同的翻译方法。
❤️🔥解题思路
要解决这个问题,我们可以使用动态规划(Dynamic Programming)的方法。动态规划是一种将问题分解成更小的子问题并逐步解决的技术。在这个问题中,我们可以逐步计算每个子字符串的解码方式。
步骤
- 初始化动态规划数组:我们使用一个数组
dp
来记录每个位置的翻译方法数。dp[i]
表示字符串前i
个字符的翻译方法数。 - 处理边界情况:首先,如果字符串为空或首字符为’0’,则没有合法的翻译方法。
- 状态转移方程:
- 如果当前位置的一个数字可以独立翻译(即不为’0’),则该位置的翻译方法数应加上前一位置的翻译方法数,即
dp[i] += dp[i - 1]
。 - 如果当前位置的两个数字组合在一起可以翻译(即其值在10到26之间),则该位置的翻译方法数应加上前两位置的翻译方法数,即
dp[i] += dp[i - 2]
。
- 如果当前位置的一个数字可以独立翻译(即不为’0’),则该位置的翻译方法数应加上前一位置的翻译方法数,即
- 返回结果:最终,
dp[n]
(n
为字符串的长度)就是我们需要的结果。
🥰代码实现
以下是具体的代码实现:
public int numDecodings(String s) {
// 如果字符串为空或以'0'开头,则没有合法的翻译方法
if (s == null || s.length() == 0) {
return 0;
}
int n = s.length();
int[] dp = new int[n + 1];
// 初始化,空字符串有一种翻译方式
dp[0] = 1;
// 如果字符串的第一个字符不为'0',则有一种翻译方式
dp[1] = s.charAt(0) == '0' ? 0 : 1;
// 动态规划求解
for (int i = 2; i <= n; i++) {
// 处理单个数字的翻译
int one = Integer.valueOf(s.substring(i - 1, i));
if (one != 0) {
dp[i] += dp[i - 1];
}
// 处理两个数字组合的翻译
if (s.charAt(i - 2) != '0') {
int two = Integer.valueOf(s.substring(i - 2, i));
if (two <= 26) {
dp[i] += dp[i - 2];
}
}
}
// 返回最后的结果
return dp[n];
}
代码解析
- 初始化部分:
dp[0]
初始化为1,表示空字符串有一种翻译方式。dp[1]
根据字符串的第一个字符是否为’0’来确定是否有合法的翻译方式。 - 主循环:从第二个字符开始,每次计算一个字符和两个字符的翻译可能性,并累加到
dp[i]
中。 - 时间复杂度:该算法的时间复杂度为O(n),其中n为字符串的长度。
😄总结
通过动态规划的方法,我们可以高效地计算出一个数字字符串有多少种不同的翻译方法。这个问题不仅考察了我们对动态规划的理解,还让我们熟悉了如何处理字符串中的边界情况和状态转移。希望通过这个例子的讲解,能够帮助你更好地理解动态规划的应用。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)