一条包含字母 A-Z
的消息通过以下的方式进行了编码:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
除了上述的条件以外,现在加密字符串可以包含字符 '*'了,字符'*'可以被当做1到9当中的任意一个数字。
给定一条包含数字和字符'*'的加密信息,请确定解码方法的总数。
同时,由于结果值可能会相当的大,所以你应当对109 + 7取模。(翻译者标注:此处取模主要是为了防止溢出)
示例 1 :
输入: "*" 输出: 9 解释: 加密的信息可以被解密为: "A", "B", "C", "D", "E", "F", "G", "H", "I".
示例 2 :
输入: "1*" 输出: 9 + 9 = 18(翻译者标注:这里1*可以分解为1,* 或者当做1*来处理,所以结果是9+9=18)
说明 :
- 输入的字符串长度范围是 [1, 105]。
- 输入的字符串只会包含字符 '*' 和 数字'0' - '9'。
只是在 91. 解码方法 的基础上加了些关于 *
的条件判断
class Solution:
def numDecodings(self, s: str) -> int:
mod = int(1e9 + 7)
n = len(s)
# dp[i - 2], dp[i - 1], dp[i]
a, b, c = 0, 1, 0
for i in range(1, n + 1):
# 1 digit
if s[i - 1] == "*":
c = 9 * b % mod
elif s[i - 1] != "0":
c = b
else:
c = 0
# 2 digits
if i > 1:
if s[i - 2] == "*" and s[i - 1] == "*":
c = (c + 15 * a) % mod
elif s[i - 2] == "*":
if s[i - 1] > "6":
c = (c + a) % mod
else:
c = (c + 2 * a) % mod
elif s[i - 1] == "*":
if s[i - 2] == "1":
c = (c + 9 * a) % mod
elif s[i - 2] == "2":
c = (c + 6 * a) % mod
elif (
s[i - 2] != "0"
and (ord(s[i - 2]) - ord("0")) * 10 + ord(s[i - 1]) - ord("0") <= 26
):
c = (c + a) % mod
a, b = b, c
return c
class Solution {
private static final int MOD = 1000000007;
public int numDecodings(String s) {
int n = s.length();
char[] cs = s.toCharArray();
// dp[i - 2], dp[i - 1], dp[i]
long a = 0, b = 1, c = 0;
for (int i = 1; i <= n; i++) {
// 1 digit
if (cs[i - 1] == '*') {
c = 9 * b % MOD;
} else if (cs[i - 1] != '0') {
c = b;
} else {
c = 0;
}
// 2 digits
if (i > 1) {
if (cs[i - 2] == '*' && cs[i - 1] == '*') {
c = (c + 15 * a) % MOD;
} else if (cs[i - 2] == '*') {
if (cs[i - 1] > '6') {
c = (c + a) % MOD;
} else {
c = (c + 2 * a) % MOD;
}
} else if (cs[i - 1] == '*') {
if (cs[i - 2] == '1') {
c = (c + 9 * a) % MOD;
} else if (cs[i - 2] == '2') {
c = (c + 6 * a) % MOD;
}
} else if (cs[i - 2] != '0' && (cs[i - 2] - '0') * 10 + cs[i - 1] - '0' <= 26) {
c = (c + a) % MOD;
}
}
a = b;
b = c;
}
return (int) c;
}
}
const mod int = 1e9 + 7
func numDecodings(s string) int {
n := len(s)
// dp[i - 2], dp[i - 1], dp[i]
a, b, c := 0, 1, 0
for i := 1; i <= n; i++ {
// 1 digit
if s[i-1] == '*' {
c = 9 * b % mod
} else if s[i-1] != '0' {
c = b
} else {
c = 0
}
// 2 digits
if i > 1 {
if s[i-2] == '*' && s[i-1] == '*' {
c = (c + 15*a) % mod
} else if s[i-2] == '*' {
if s[i-1] > '6' {
c = (c + a) % mod
} else {
c = (c + 2*a) % mod
}
} else if s[i-1] == '*' {
if s[i-2] == '1' {
c = (c + 9*a) % mod
} else if s[i-2] == '2' {
c = (c + 6*a) % mod
}
} else if s[i-2] != '0' && (s[i-2]-'0')*10+s[i-1]-'0' <= 26 {
c = (c + a) % mod
}
}
a, b = b, c
}
return c
}