【动态规划】leetcode91 解码方法(java)
题目详情
题目解析
定义dp 数组,dp[i] 用以表示字符串 s 从0 到 i 的子字符串的解码方式的总数,当求解dp[i] 时 考虑当前位置s.charAt(i) 和 dp[i - 1] dp[i - 2];
一共有以下几种情况:
- s.charAt(i) == ‘0’ : 若出现连续两个0 则返回 0; 否则 dp[i] = dp[i - 2]
- s.charAt(i) != ‘0’ 但 s.charAt(i) 与 s.charAt(i - 1) 能组成 1~ 26之间的数。dp[i] = dp[i - 1] + dp[i - 2]
- s.charAt(i) != ‘0’ 但 s.charAt(i) 与 s.charAt(i - 1) 能组成 1~ 26之间的数.dp[i] = dp[i - 1]
class Solution {
public int numDecodings(String s){
if(s.length() == 0)
return 0;
if(s.charAt(0) == '0')
return 0;
if(s.length() == 1)
return 1;
int[] dp = new int[s.length() + 1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2; i < s.length() + 1; i ++){
int index = i - 1;
if(s.charAt(index) == '0'){
if(s.charAt(index - 1) == '1' ||s.charAt(index - 1) == '2')
// 必须与前一个字符结合
dp[i] = dp[i - 2];
else
// 不能与前一个数字组成 1 ~ 26 之间的数
return 0;
}else if(Integer.parseInt(s.substring(index - 1, index + 1)) > 26
|| s.charAt(index - 1) == '0'){
// 与前一个数字结合大于26 或者前一个数字是0 则不能与前一个数字结合
dp[i] = dp[i - 1];
}else{
// 既可以单独作为一个字母,也可以与前一个字符结合组成一个字母
dp[i] = dp[i - 1] + dp[i - 2];
}
}
return dp[s.length()];
}
}