题目描述
A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message "12"
, it could be decoded as "AB"
(1 2) or "L"
(12).
The number of ways decoding "12"
is 2.
例如"12"既可以解码为“AB”,也可以解码为“L”。因此,信息“12”的解码方式有2种。
解题思路
乍一看题目,很容易想到走n阶楼梯,每步智能走1阶或2阶,问有多少种走法?的题目。的确,思考此题的方式和走楼梯类似,但要考虑的情况变得复杂了。
我们以s表示已编码的字符串,则s.length()为其长度,我那个ways[]数组来记录s.substring(0,i)【2<i<s.length()】对应的解码方式,ways[0]和ways[1]来记录
s.length()=1和2的情况。
那么对于任意i【2<i<s.length()】,我们有:
首先,考虑末一位的情况:
- s.charAt(i)==‘0’,如果s.charAt(i)==‘1’或s.charAt(i)==‘2’,那么ways[i] = ways[i - 2],否则ways[i] = 0;
- s.charAt(i)!=‘0’,那么ways[i] = ways[i] + ways[i - 1],然后再考虑末两位的情况。
其次,考虑末两位的情况:
- s.charAt(i-1) == '1' && s.charAt(i)!= '0',那么ways[i] = ways[i] + ways[i - 2];
- s.charAt(i-1) == '2' && s.charAt(i)!= '0' && s.charAt(i) <= '6',那么ways[i] = ways[i] + ways[i - 2];
- 其他情况ways[i]不变
代码
public int numDecodings(String s) {
if (s == null || s.length() == 0)
return 0;
if (s.length() == 1) {
if (s.equals("0")) {
return 0;
} else {
return 1;
}
}
if (s.length() == 2) {
//首位为0,则解码数为0
if (s.charAt(0) == '0')
return 0;
int value = Integer.parseInt(s);
if (value == 10 || value == 20)
return 1;
if (value <= 26)
return 2;
if (value % 10 == 0)
return 0;
return 1;
}
int[] ways = new int[s.length()];
ways[0] = numDecodings(s.substring(0,1));
ways[1] = numDecodings(s.substring(0,2));
for(int i = 2;i < s.length();i++){
ways[i] = 0;
if(s.charAt(i)!= '0'){
ways[i] += ways[i - 1];
}
if(s.charAt(i-1) == '1' || (s.charAt(i-1) == '2' && s.charAt(i) <= '6')){
ways[i] += ways[i - 2];
}
}
return ways[s.length() - 1];
}