Skip to content

Commit 8ff31fa

Browse files
author
wangpeng
committed
feat(HARD): add _639_numDecodings
1 parent 18d48fb commit 8ff31fa

File tree

2 files changed

+103
-1
lines changed

2 files changed

+103
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![996.icu](https://img.shields.io/badge/link-996.icu-red.svg)](https://996.icu)
44

55
## 说明
6-
- leetcode练习,坚持每天一道
6+
- leetcode练习,坚持每天一道,目前已完成147道
77
- 解题语言是Java
88
- 每道题都是可编译运行的
99
- 每道题有自己的方法和他人优秀解法
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package pp.arithmetic.leetcode;
2+
3+
/**
4+
* Created by wangpeng on 2019-04-26.
5+
* 639. 解码方法 2
6+
* <p>
7+
* 一条包含字母 A-Z 的消息通过以下的方式进行了编码:
8+
* <p>
9+
* 'A' -> 1
10+
* 'B' -> 2
11+
* ...
12+
* 'Z' -> 26
13+
* 除了上述的条件以外,现在加密字符串可以包含字符 '*'了,字符'*'可以被当做1到9当中的任意一个数字。
14+
* <p>
15+
* 给定一条包含数字和字符'*'的加密信息,请确定解码方法的总数。
16+
* <p>
17+
* 同时,由于结果值可能会相当的大,所以你应当对10^9 + 7取模。(翻译者标注:此处取模主要是为了防止溢出)
18+
* <p>
19+
* 示例 1 :
20+
* <p>
21+
* 输入: "*"
22+
* 输出: 9
23+
* 解释: 加密的信息可以被解密为: "A", "B", "C", "D", "E", "F", "G", "H", "I".
24+
* 示例 2 :
25+
* <p>
26+
* 输入: "1*"
27+
* 输出: 9 + 9 = 18(翻译者标注:这里1*可以分解为1,* 或者当做1*来处理,所以结果是9+9=18)
28+
* 说明 :
29+
* <p>
30+
* 输入的字符串长度范围是 [1, 10^5]。
31+
* 输入的字符串只会包含字符 '*' 和 数字'0' - '9'。
32+
*
33+
* @see <a href="https://leetcode-cn.com/problems/decode-ways-ii/">decode-ways-ii</a>
34+
*/
35+
public class _639_numDecodings {
36+
37+
public static void main(String[] args) {
38+
_639_numDecodings numDecodings = new _639_numDecodings();
39+
System.out.println(numDecodings.numDecodings("1*"));
40+
}
41+
42+
public static final int mod = (int) Math.pow(10, 9) + 7;
43+
44+
/**
45+
* LO上优秀解法
46+
* 解题关键点,理清楚各种情况下的个数可能性
47+
*
48+
* @param s
49+
* @return
50+
*/
51+
public int numDecodings(String s) {
52+
if (s == null || s.length() == 0) {
53+
return 0;
54+
}
55+
char[] str = s.toCharArray();
56+
57+
long[] dp = new long[str.length + 1];
58+
dp[str.length] = 1;
59+
for (int i = str.length - 1; i >= 0; i--) {
60+
if (str[i] == '0') {
61+
dp[i] = 0;
62+
} else {
63+
long res = dp[i + 1];
64+
if (str[i] == '*') {
65+
res = (9 * res) % mod;
66+
}
67+
if (i + 1 < str.length) {
68+
long tmp = dp[i + 2];
69+
if (str[i] != '*') {
70+
if (str[i + 1] != '*') {
71+
if ((str[i] - '0') * 10 + str[i + 1] - '0' < 27) {
72+
res = (res + tmp) % mod;
73+
}
74+
} else {
75+
if (str[i] < '3') {
76+
if (str[i] == '1') {
77+
res = (res + 9 * tmp) % mod;
78+
} else if (str[i] == '2') {
79+
res = (res + 6 * (tmp)) % mod;
80+
}
81+
}
82+
}
83+
} else {
84+
if (str[i + 1] != '*') {
85+
if (10 + str[i + 1] - '0' < 27) {
86+
res = (res + tmp) % mod;
87+
}
88+
if (20 + str[i + 1] - '0' < 27) {
89+
res = (res + tmp) % mod;
90+
}
91+
} else {
92+
res = (res + 15 * tmp) % mod;
93+
}
94+
}
95+
}
96+
dp[i] = res;
97+
}
98+
}
99+
100+
return (int) (dp[0]);
101+
}
102+
}

0 commit comments

Comments
 (0)