动态规划解决字符串组合问题

题目链接-来源:力扣(LeetCode)

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是”bccfi”, “bwfi”, “bczi”, “mcfi”和”mzi”

思路:

显然,对于一位数字,确定地对应’0’~’9’中的某一个,所以只有 1 种翻译。我们再将它之前的数字组合考虑,如果组合而成的数字大于 ‘25’,显然是无法翻译的,也就是 0 种;反之,我们又能多出 1 种翻译。
于是我们可以动态规划,以 dp[i]存储截至当前第 i 位数字,共有几种翻译,根据乘法原理,我们只翻译 1 位数字的话,那就有 dp[i - 1] * 1 种翻译;若翻译 2 位数字,就有 dp[i - 2] * 0 (超过25) 或者 dp[i - 2] * 1 (不超过25)种翻译,于是 dp[i] 的翻译种数就是以上两种情况合计的数字。我们需要特别将 dp[0] 和 dp[1] 初始化为 1。
时间复杂度:O(n)
空间复杂度:O(n)

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int translateNum(int num) {
String s = Integer.toString(num);
int n = s.length();

int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 1; i < n; i++) {
dp[i + 1] = dp[i];
int flag = (s.charAt(i - 1) - '0') * 10 + (s.charAt(i) - '0');
if (flag < 26 && flag >= 10) {
dp[i + 1] += dp[i - 1];
}
}
return dp[n];
}
}