详细见:leetcode.com/problems/decode-ways
Java Solution: github
package leetcode;
import java.util.ArrayList;
/*
* 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.
*/
public class P091_DecodeWays {
public static void main(String[] args) {
// System.out.println(new Solution().numDecodings("102020"));
// System.out.println(new Solution().numDecodings("1120121"));
// System.out.println(new Solution().numDecodings("1127121"));
System.out.println(new Solution().numDecodings("10"));
}
/*
* 算法题,很多都是仔细分析
* 别慌,一慌什么都完了
* AC
* 在慌的时候,WA好多次
* 5 ms
*/
static class Solution {
int[] arr = null;
int count = 1;
ArrayList<Integer> help = null;
final int sign_init = -1, sign_0 = 0, sign_1 = 1,
sign_2 = 2, sign_3_7 = 37, sign_else = 3;
public int numDecodings(String s) {
if (s == null || s.length() == 0) {
return 0;
} else if (s.equals("0")) {
return 0;
}
arr = new int[s.length()];
help = new ArrayList<Integer>();
help.add(1);
help.add(2);
for (int i = 0; i != arr.length; i ++) {
arr[i] = s.charAt(i) - '0';
}
int i = 0, pre_sign = sign_init;
for (int j = 0; j != arr.length; j ++) {
if (arr[j] < 0 || arr[j] > 26) {
//出现非法输入
if (i < j) {
add(i, j - 1);
}
i = j + 1;
return 0;
}
//所有数字 [0 , 26]
if (arr[j] == 0) {
// 0的情况
if (pre_sign == sign_1 || pre_sign == sign_2) {
count *= add(i, j - 2);
i = j + 1;
} else {
return 0;
}
if (j == arr.length - 1) {
count *= add(i, j);
}
pre_sign = sign_0;
} else if (arr[j] == 1) {
// 1的情况
if (j == arr.length - 1) {
count *= add(i, j);
}
pre_sign = sign_1;
} else if (arr[j] == 2) {
// 需要注意后者是否[0 ~ 6]
if (j == arr.length - 1) {
count *= add(i, j);
}
pre_sign = sign_2;
} else if (arr[j] < 7) {
// 3 4 5 6
// 只是需要注意前面是否是2
if (pre_sign == sign_1 || pre_sign == sign_2) {
count *= add(i, j);
i = j + 1;
} else {
// 包含
// pre_sign == sign_init
// pre_sign == sign_0
// pre_sign == sign_3_7
// pre_sign == sign_else
i = j + 1;
}
pre_sign = sign_3_7;
} else {
// 7 8 9
// 对arr[j] < 7的情况,只是不需要考虑2的情况
if (pre_sign == sign_1) {
count *= add(i, j);
i = j + 1;
} else if (pre_sign == sign_2) {
count *= add(i, j - 1);
i = j + 1;
} else {
// 包含
// pre_sign == sign_init
// pre_sign == sign_0
// pre_sign == sign_3_7
// pre_sign == sign_else
i = j + 1;
}
pre_sign = sign_else;
}
}
return count;
}
private int add(int i, int j) {
if (i > j || i < 0 || j < 0) {
return 1;
} else if (j - i < help.size()) {
return help.get(j - i);
} else {
int k = help.size();
int k1 = k - 1;
int k2 = k - 2;
for (; k <= j - i; k ++) {
help.add(help.get(k1 ++) + help.get(k2 ++));
}
return help.get(j - i);
}
}
}
}
C Solution: github
/*
url: leetcode.com/problems/decode-ways
AC 3ms 22.50%
*/
#include <stdio.h>
#include <stdlib.h>
int numDecodings(char* s) {
char c;
int i = 0;
int cnt = 0, p1 = 0, p2 = 0;
int v = 0;
while (1) {
c = s[i];
p2 = p1;
p1 = cnt;
if (c == '\0') break;
if (i == 0) {
if (c == '0') return 0;
cnt = 1;
} else {
v = (s[i-1]-'0') * 10 + s[i] - '0';
if (i == 1) {
if (v % 10 == 0) {
if (v > 20 || v == 0) return 0;
} else {
if (v > 10 && v < 27) cnt = 2;
if (v > 0 && v < 10) cnt = p1;
}
} else {
if (v % 10 == 0) {
if (v > 20 || v == 0) return 0;
cnt = p2;
} else {
if (v > 10 && v < 27) cnt += p2;
if (v > 0 && v < 10) cnt = p1;
}
}
}
i ++;
}
return cnt;
}
int main() {
char* s = "10298212029821202120821272721202812928221721202821278171";
printf("answer is %d\r\n", numDecodings(s));
return 0;
}
Python Solution: github
#coding=utf-8
'''
url: leetcode.com/problems/decode-ways
@author: zxwtry
@email: zxwtry@qq.com
@date: 2017年4月23日
@details: Solution: 52ms 60.05%
'''
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
sn = 0 if s == None else len(s)
if sn == 0 or s[0] == '0': return 0
v1, a1, a2 = int(s[0]), 1, 1
for i in range(1, sn):
v0 = int(s[i])
if v0 == 0:
if v1 in {1, 2}:
a2, a1=a1, a2
else: return 0
elif v1 == 1 or (v1==2 and v0<7):
a2, a1 = a1, a1+a2
else: a2, a1 = a1, a1
v1 = v0
return a1
if __name__ == "__main__":
m = [
'0',
'1',
'9',
'10',
'11',
'19',
'20',
'21',
'29',
'30',
'88',
]
for s in m:
print("%s \t %d" % (s, Solution().numDecodings(s)))