一条包含字母 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) 。
本次从尾开始遍历至头是较好的选择
如果开头为0 ,则无法编码 dp【i】=0;
对226 进行分析
dp【2】 的情况 nums!= 0 所以 dp[2]=1 dp[1] 26 因为 nums【1】*10 + nums【2】=26 不大于 26 所以 dp【1】= 2 ;
dp【0】226 nums[0]*10+nums[1]=22<26 所以dp【0】=dp[1]+dp【2】 =3
如果 为 426 nums【0】*10+nums【1】=42 》26 , dp[0]=dp[1]=2; 即 4 ,26 与 4,2,6
所以转移方程出现 *if(nums[i]10+nums[i+1]<=10) dp [i]=dp[i+1]+dp[i+2] else dp[i]=dp[i+1]
从原理上讲 定义开始的数字为 i 若 nums[i]*10+nums[i+1]大于了26 ,说明他们一定要分开放 那么对于 以i开头的组合其实是与i+1 开头组合的个数一样的
若 nums[i]*10+nums[i+1] <26 那么可以吧 i 与 i+1 去掉 看以i+2 开头的组合个数 加上 吧i视为个体,以i+1 为开头的组合
同时注意 开头数字为0的组合情况为 0
class Solution {
public int numDecodings(String s) {
//dp[i] 为 数 i 时 其组成方式 个数
//本次从尾开始遍历至头是较好的选择
// 如果开头为0 ,则无法编码 dp【i】=0;
/*
对226 进行分析
dp【2】 的情况 nums!= 0 所以 dp[2]=1 dp[1] 26 因为 nums【1】*10 + nums【2】=26 不大于 26 所以 dp【1】= 2 ;
dp【0】226 nums[0]*10+nums[1]=22<26 所以dp【0】=dp[1]+dp【2】 =3
如果 为 426 nums【0】*10+nums【1】=42 》26 , dp[0]=dp[1]=2; 即 4 ,26 与 4,2,6
所以转移方程出现 if(nums[i]*10+nums[i+1]<=10) dp [i]=dp[i+1]+dp[i+2] else dp[i]=dp[i+1]
从原理上讲 定义开始的数字为 i 若 nums[i]*10+nums[i+1]大于了26 ,说明他们一定要分开放 那么对于 以i开头的组合其实是与i+1 开头组合的个数一样的
若 nums[i]*10+nums[i+1] <26 那么可以吧 i 与 i+1 去掉 看以i+2 开头的组合个数 加上 吧i视为个体,以i+1 为开头的组合
同时注意 开头数字为0的组合情况为 0
*/
int [] dp =new int [s.length()+1];
int len =s.length();
if (s == null || s.length() == 0) {
return 0;
}
dp[len]=1;
//检测末尾是否为0
if(s.charAt(len-1)=='0'){
dp[len-1]=0;
}
else{
dp[len-1]=1;
}
for(int i=len-2;i>=0;i--){
if (s.charAt(i) == '0') {
dp[i] = 0;
continue;
}
if ((s.charAt(i) - '0') * 10 + (s.charAt(i + 1) - '0') <= 26) {
dp[i] = dp[i + 1] + dp[i + 2];
}
else {
dp[i] = dp[i + 1];
}
}
return dp[0];
}
}
314

被折叠的 条评论
为什么被折叠?



