分割整数构成字母字符串(动态规划)
题目:
一条包含字母 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) 。
算法思想:
创建一个数组,dp[] 长度为 n + 1 ;
- 如果字符串为空,或者字符串首字母为 ‘0’ 那么返回 0 ;无法编码;
- 初始化dp=[0,…,0],长度为n+1,dp[0]=1,dp[1]=1,dp[1]=1表示第一位的解码方法,dp[0]的作用,在于两位时,如:“12”,dp[2]=dp[1]+dp[0]。
- 遍历s,遍历区间[1,n):
- 如果s[i] == ‘0’ , 且 s[i - 1] == 1 || s[i - 1] == 2, 则dp[i + 1] = dp[i - 1]
- 否则:
- s[i - 1] 为 1 ,或者 s[i - 2] 为 2 且 s[i] <= 6 && s[i] >= 1, 则 dp[i + 1] = dp[i] + dp[i - 1] ;
- 否则: dp[i + 1] = dp[i] ;
public int numDecodings(String s) {
int len = s.length();
if (s == null || len == 0 || s.charAt(0) == '0') {
return 0;
}
int[] dp = new int[len + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 1; i < len; i++) {
int num1 = Integer.valueOf(s.substring(i, i + 1));
int num2 = Integer.valueOf(s.substring(i - 1, i));
if (num1 == 0) {
if (num2 == 1 || num2 == 2) {
dp[i + 1] = dp[i - 1];
} else {
return 0;
}
} else {
dp[i + 1] = dp[i] + dp[i - 1];
if (num2 == 1 || (num2 == 2 && (num1 <= 6 && num1 >= 1))) {
dp[i + 1] = dp[i] + dp[i - 1];
} else {
dp[i + 1] = dp[i];
}
}
}
return dp[len];
}
总结:每道算法题都应该想清楚思路,再开始写代码,不然逻辑混乱,就是在瞎想。