版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxm1306192988/article/details/82077850
题目描述
一条包含字母 A-Z
的消息通过以下方式进行了编码:
‘A’ -> 1
‘B’ -> 2
…
‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。
示例 1:
输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)。
示例 2:
输入: “226”
输出: 3
解释: 它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6) 。
题解:
用深度优先搜索,每次组合 1个或2个字符,超时
class Solution {
int cnt = 0;
public int numDecodings(String s) {
if (s == null || s.length() == 0) {
return cnt;
}
if (s.charAt(0) == '0') {
return 0;
}
dfs(s, "");
return cnt;
}
private void dfs(String s, String sub) {
if (s.equals("")) {
cnt++;
}
for (int i = 1; i <= 2; i++) {
if (s.length() < i) {
continue;
}
String ss = s.substring(0, i);
if (ss.charAt(0) == '0') {
continue;
}
int val = Integer.valueOf(ss);
if (val > 26 || val < 1) {
continue;
}
dfs(s.substring(i), sub + ss);
}
}
}
方法二:动态规划
确定状态:
dp[i] 表示到第i个数字有多少种不同的翻译方法
初始状态:
dp[0] = 1; 第0个数字要表示1种
dp[1] = s.charAt(0) == ‘0’ ? 0 : 1; 第1个数字如果不为0则表示1种
终止状态:
dp[n]
状态转移方程:
dp[n]=dp[n-1]+dp[n-2] 以一个字符直接拼在后面,和前一个字符组成二位字符,拼在后面。 两种可能都有判断条件。
class Solution {
public int numDecodings(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int n = s.length();
int[] dp = new int[n + 1];// dp[i] 表示到第i个数字有多少种不同的翻译方法
dp[0] = 1;
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) // 如果不为0,直接并在后面
dp[i] += dp[i - 1];
if (s.charAt(i - 2) == '0') // 如果它前面那个数字是0,则不能和他前面那个数字组成二位数
continue;
int two = Integer.valueOf(s.substring(i - 2, i)); // 和他前面那个数字组成二位数
if (two <= 26) // 如果满足条件,直接并在后面
dp[i] += dp[i - 2];
}
return dp[n];
}
}