【LeetCode每日一题】解码方法
解码方法
1、题目描述
一条包含字母 A-Z 的消息通过以下映射进行了 编码 :
'A' -> 1
'B' -> 2
...
'Z' -> 26
示例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" 在映射中并不等价)。
2、算法思想
核心思想:
采用动态线性规划的思想,前面1个解码次数解出来,再求2个的解码次数,再求3个的,一次类推
就是先求出前i个解码次数,然后就可以得到第i-1个次数
实现思路:
1、定义一个fn,用于存储前n个数的解码次数,没经过一个数记录一下它的解码次数
2、考虑特殊情况
(1)、当第i个数不为0的时候
f[i] = f[i-1]
(2)、当第i个数和第i-1个数可以组合的时候(即s[i-1] != 0,而且 s[i-1] + s[i-2] <=2)
f[i] = f[i-2]
(3)、当上述条件都满足的时候,这两个要相加,所以在后面的代码中可以看到
f[i] += f[i-1]
f[i] += f[i-2]
3、代码实现
package com.java;
public class Day21_Solution {
public int numDecodings(String s) {
int n = s.length();
int[] f = new int[n+1];
f[0] = 1;
for (int i=1;i<=n;i++) {
if (s.charAt(i-1) != '0') {
f[i] += f[i-1];
}
if (i>1 && s.charAt(i-2) != '0' && ((s.charAt(i-2) - '0')*10 + (s.charAt(i-1) - '0')) <=26) {
f[i] += f[i-2];
}
}
return f[n];
}
}