一条包含字母 A-Z
的消息通过以下映射进行了 编码 :
'A' -> 1 'B' -> 2 ... 'Z' -> 26
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,"11106"
可以映射为:
"AAJF"
,将消息分组为(1 1 10 6)
"KJF"
,将消息分组为(11 10 6)
注意,消息不能分组为 (1 11 06)
,因为 "06"
不能映射为 "F"
,这是由于 "6"
和 "06"
在映射中并不等价。
给你一个只含数字的 非空 字符串 s
,请计算并返回 解码 方法的 总数 。
题目数据保证答案肯定是一个 32 位 的整数。
示例 1:
输入:s = "12" 输出:2 解释:它可以解码为 "AB"(1 2)或者 "L"(12)。
示例 2:
输入:s = "226" 输出:3 解释:它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。
示例 3:
输入:s = "0" 输出:0 解释:没有字符映射到以 0 开头的数字。 含有 0 的有效映射是 'J' -> "10" 和 'T'-> "20" 。 由于没有字符,因此没有有效的方法对此进行解码,因为所有数字都需要映射。
示例 4:
输入:s = "06" 输出:0 解释:"06" 不能映射到 "F" ,因为字符串含有前导 0("6"
和"06"
在映射中并不等价)。
提示:
1 <= s.length <= 100
s
只包含数字,并且可能包含前导零。
Related Topics
- 首位为0的定然不符合
- 如果字符串长度只有1的话,肯定只有一种情况直接先返回
- 如果字符串长度大于2,对第二位单独做个情况处理。
- 如果第二个字符串为0,此时他不能单独处理,需要跟前一位合并解析
- 如果合并起来大于26,那么是解析不到对应的,直接返回0
- 如果合并起来不大于26,那么此时应该是10或者20的情况,只有一种解析方式,此时的组合数为1
- 如果第二个字符串不为0
- 如果和前面组合起来小于等于26,说明可以分开也可以组合起来解析,此时组合数为1
- 如果大于26,则只能分开解析。可能组合数仍然为1
- 如果第二个字符串为0,此时他不能单独处理,需要跟前一位合并解析
- 从第三位往后开始解析处理,假设当前位置的索引为i
- 和上面类似,如果当前字符为‘0’,只能和前面字符组合起来解析
- 如果值大于26,或者前一个数字也为0,无法解析,返回0
- 否则当前位置一定为10或者20,当前位置【i】和前一位【i-1】是一个整体,这样能解析出来的组合数量和【i-2】位能获得的组合数量是一致的
- 如果当前位置字符不为0,
- 如果和前面组合起来的话大于26,说明不能和前面的值组合起来解析,则当前位置能获得的组合数量和前面一位【i-1】一致
- 如果不大于26
- 如果前一位为0,即组合起来的值小于等于9,则不能和前一位组合,可能的组合数依旧和前一位【i-1】的组合数一致
- 如果不为0,那么可能组合成11到19和21到26之间的数值,即说明可以和前一位组合(值等于【i-2】位的),也可以不组合(值等于【i-1】位的)。即为【i-1】加上【i-2】位的和
- 和上面类似,如果当前字符为‘0’,只能和前面字符组合起来解析
class Solution {
public int numDecodings(String s) {
if (s.length() == 0 || s.charAt(0) == '0' ){
return 0;
}
if (s.length() == 1){
return 1;
}
int[] dp = new int[s.length()];
dp[0] = 1;
int i = 1;
int curNum = s.charAt(i)-'0';
int withBefore = (s.charAt(i-1)-'0') * 10 + (s.charAt(i)-'0');
if (curNum==0 ){
if (withBefore > 26 || withBefore ==0){
return 0;
}
dp[i] = 1;
}else{
if (withBefore <= 26){
dp[i] = 2;
}else{
dp[i] = 1;
}
}
i++;
for (; i < dp.length; i++) {
curNum = s.charAt(i)-'0';
withBefore = (s.charAt(i-1)-'0') * 10 + (s.charAt(i)-'0');
if (curNum == 0){
if (withBefore > 26 || withBefore ==0){
return 0;
}
dp[i] = dp[i-2];
}else{
if (withBefore > 26){
dp[i] = dp[i-1];
}else {
if (withBefore>9){
dp[i] = dp[i-1] + dp[i-2];
}else {
dp[i] = dp[i-1];
}
}
}
}
return dp[dp.length-1];
}
}
这题动归本身并不复杂,复杂的各种逻辑情况的判定分析,分支略有点多。
发表评论