[LeetCode] 639. Decode Ways II 解码方法 II
A message containing letters from A-Z is being encoded to numbers using the following mapping way:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers from 1 to 9.
Given the encoded message containing digits and the character '*', return the total number of ways to decode it.
Also, since the answer may be very large, you should return the output mod 109 + 7.
Example 1:
Input: "*"
Output: 9
Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I".
Example 2:
Input: "1*"
Output: 9 + 9 = 18
Note:
- The length of the input string will fit in range [1, 105].
- The input string will only contain the character '*' and digits '0' - '9'.
91. Decode Ways 的拓展,这次字符串里面可能含有'*', 它可以1~9中的任何一个,求总的解码方法数。
解法:还是DP,主要是如何处理'*'。
Java:
public int numDecodings(String s) {
/* initial conditions */
long[] dp = new long[s.length()+1];
dp[0] = 1;
if(s.charAt(0) == '0'){
return 0;
}
dp[1] = (s.charAt(0) == '*') ? 9 : 1;
/* bottom up method */
for(int i = 2; i <= s.length(); i++){
char first = s.charAt(i-2);
char second = s.charAt(i-1);
// For dp[i-1]
if(second == '*'){
dp[i] += 9*dp[i-1];
}else if(second > '0'){
dp[i] += dp[i-1];
}
// For dp[i-2]
if(first == '*'){
if(second == '*'){
dp[i] += 15*dp[i-2];
}else if(second <= '6'){
dp[i] += 2*dp[i-2];
}else{
dp[i] += dp[i-2];
}
}else if(first == '1' || first == '2'){
if(second == '*'){
if(first == '1'){
dp[i] += 9*dp[i-2];
}else{ // first == '2'
dp[i] += 6*dp[i-2];
}
}else if( ((first-'0')*10 + (second-'0')) <= 26 ){
dp[i] += dp[i-2];
}
}
dp[i] %= 1000000007;
}
/* Return */
return (int)dp[s.length()];
}
Python:
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
if len(s) == 0 or s[0] == '0':
return 0 dp = [0] * (len(s) + 1)
dp[0] = 1
dp[1] = 9 if s[0] == '*' else 1 for i in xrange(2, len(dp)):
first = s[i-2]
second = s[i-1]
# for dp[i-1]
if second == '*':
dp[i] = dp[i-1] * 9
elif second != '0':
dp[i] = dp[i-1] # for dp[i-2]
if first == '*':
if second == '*':
dp[i] += 15 * dp[i-2]
elif second <= '6':
dp[i] += 2 * dp[i-2]
else:
dp[i] += dp[i-2]
elif first == '1' or first == '2':
if second == '*':
if first == '1':
dp[i] += 9 * dp[i-2]
else:
dp[i] += 6 * dp[i-2]
elif first == '1' or (first == '2' and second <= '6'):
dp[i] += dp[i-2] dp[i] %= 1000000007 return dp[-1]
Python:
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
M, W = 1000000007, 3
dp = [0] * W
dp[0] = 1
dp[1] = 9 if s[0] == '*' else dp[0] if s[0] != '0' else 0
for i in xrange(1, len(s)):
if s[i] == '*':
dp[(i + 1) % W] = 9 * dp[i % W]
if s[i - 1] == '1':
dp[(i + 1) % W] = (dp[(i + 1) % W] + 9 * dp[(i - 1) % W]) % M
elif s[i - 1] == '2':
dp[(i + 1) % W] = (dp[(i + 1) % W] + 6 * dp[(i - 1) % W]) % M
elif s[i - 1] == '*':
dp[(i + 1) % W] = (dp[(i + 1) % W] + 15 * dp[(i - 1) % W]) % M
else:
dp[(i + 1) % W] = dp[i % W] if s[i] != '0' else 0
if s[i - 1] == '1':
dp[(i + 1) % W] = (dp[(i + 1) % W] + dp[(i - 1) % W]) % M
elif s[i - 1] == '2' and s[i] <= '6':
dp[(i + 1) % W] = (dp[(i + 1) % W] + dp[(i - 1) % W]) % M
elif s[i - 1] == '*':
dp[(i + 1) % W] = (dp[(i + 1) % W] + (2 if s[i] <= '6' else 1) * dp[(i - 1) % W]) % M
return dp[len(s) % W]
C++:
class Solution {
public:
int numDecodings(string s) {
int n = s.size(), M = 1e9 + 7;
vector<long> dp(n + 1, 0);
dp[0] = 1;
if (s[0] == '0') return 0;
dp[1] = (s[0] == '*') ? 9 : 1;
for (int i = 2; i <= n; ++i) {
if (s[i - 1] == '0') {
if (s[i - 2] == '1' || s[i - 2] == '2') {
dp[i] += dp[i - 2];
} else if (s[i - 2] == '*') {
dp[i] += 2 * dp[i - 2];
} else {
return 0;
}
} else if (s[i - 1] >= '1' && s[i - 1] <= '9') {
dp[i] += dp[i - 1];
if (s[i - 2] == '1' || (s[i - 2] == '2' && s[i - 1] <= '6')) {
dp[i] += dp[i - 2];
} else if (s[i - 2] == '*') {
dp[i] += (s[i - 1] <= '6') ? (2 * dp[i - 2]) : dp[i - 2];
}
} else { // s[i - 1] == '*'
dp[i] += 9 * dp[i - 1];
if (s[i - 2] == '1') dp[i] += 9 * dp[i - 2];
else if (s[i - 2] == '2') dp[i] += 6 * dp[i - 2];
else if (s[i - 2] == '*') dp[i] += 15 * dp[i - 2];
}
dp[i] %= M;
}
return dp[n];
}
};
C++:
class Solution {
public:
int numDecodings(string s) {
long e0 = 1, e1 = 0, e2 = 0, f0, f1, f2, M = 1e9 + 7;
for (char c : s) {
if (c == '*') {
f0 = 9 * e0 + 9 * e1 + 6 * e2;
f1 = e0;
f2 = e0;
} else {
f0 = (c > '0') * e0 + e1 + (c <= '6') * e2;
f1 = (c == '1') * e0;
f2 = (c == '2') * e0;
}
e0 = f0 % M;
e1 = f1;
e2 = f2;
}
return e0;
}
};
类似题目:
[LeetCode] 91. Decode Ways 解码方法
All LeetCode Questions List 题目汇总
[LeetCode] 639. Decode Ways II 解码方法 II的更多相关文章
- leetcode 639 Decode Ways II
首先回顾一下decode ways I 的做法:链接 分情况讨论 if s[i]=='*' 考虑s[i]单独decode,由于s[i]肯定不会为0,因此我们可以放心的dp+=dp1 再考虑s[i-1] ...
- LeetCode OJ:Decode Ways(解码方法)
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- leetcode 91 Decode Ways I
令dp[i]为从0到i的总方法数,那么很容易得出dp[i]=dp[i-1]+dp[i-2], 即当我们以i为结尾的时候,可以将i单独作为一个字母decode (dp[i-1]),同时也可以将i和i-1 ...
- Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理) 题目描述 一条报文包含字母A-Z,使用下面的字母-数字映射进行解码 'A' -> 1 'B' -> 2 ...
- leetcode@ [91] Decode Ways (Dynamic Programming)
https://leetcode.com/problems/decode-ways/ A message containing letters from A-Z is being encoded to ...
- [LeetCode] Decode Ways II 解码方法之二
A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...
- [LeetCode] 91. Decode Ways 解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- leetcode[90] Decode Ways
题目:如下对应关系 'A' -> 1 'B' -> 2 ... ‘Z’ -> 26 现在给定一个字符串,返回有多少种解码可能.例如:Given encoded message &qu ...
- LeetCode(91):解码方法
Medium! 题目描述: 一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计 ...
随机推荐
- Python的logging模块基本用法
Python 的 logging 模块的简单用法 在服务器部署时,往往都是在后台运行.当程序发生特定的错误时,我希望能够在日志中查询.因此这里熟悉以下 logging 模块的用法. logging 模 ...
- MP4文件批量转码成MP3
需求背景:最近为了学python爬虫,在论坛里找了不少视频教程,非常棒.但有时看视频不方便,就想着能否把视频批量转码成音频,这样在乘坐地铁公交的时候也能学习了. 解决路径:有了需求,我首先在论坛里搜了 ...
- CF938G Shortest Path Queries 和 CF576E Painting Edges
这两道都用到了线段树分治和按秩合并可撤销并查集. Shortest Path Queries 给出一个连通带权无向图,边有边权,要求支持 q 个操作: x y d 在原图中加入一条 x 到 y 权值为 ...
- SparkSQL读写外部数据源-jext文件和table数据源的读写
object ParquetFileTest { def main(args: Array[String]): Unit = { val spark = SparkSession .builder() ...
- Djiango-富文本编辑器
借助富文本编辑器,网站的编辑人员能够像使用offfice一样编写出漂亮的.所见即所得的页面.此处以tinymce为例,其它富文本编辑器的使用也是类似的. 在虚拟环境中安装包. pip install ...
- Markdown 设置字体大小颜色及背景色
一.更改字体.大小.颜色 <font face="黑体">我是黑体字</font><font face="微软雅黑">我是微 ...
- Comet OJ - Contest #14 转转的数据结构题 珂朵莉树+树状数组
题目链接: 题意:有两个操作 操作1:给出n个操作,将区间为l到r的数字改为x 操作2:给出q个操作,输出进行了操作1中的第x到x+y-1操作后的结果 解法: 把询问离线,按照r从小到大排序 每次询问 ...
- dinoql 使用nodejs 运行的几个问题
dinoql 是一个很不错的javascript objects 查询处理方案,基于graphql,当前版本有点问题 node 环境运行 ReferenceError: window is not d ...
- 【JZOJ6210】【20190612】wsm
题目 定义两个非递减数列的笛卡尔和数列\(C = A \oplus B\) 为\((A_i+B_j)\)排序后的非递减数列 \(W\)组询问,问有多少对可能的数列,满足: \(|C|=s,|A| = ...
- 洛谷P3620 [APIO/CTSC 2007] 数据备份
题目 贪心+堆. 一般贪心题用到堆的时候都会存在一种反悔操作,因此这个题也不例外. 首先电缆一定是连接两个相邻的点的,这很好证明,其次一个点只能被一条电缆连接,所以我们通过选这个电缆,不选相邻电缆和选 ...