[LeetCode] Decode Ways 解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
Example 1:
Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226"
Output: 3
Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
这道题要求解码方法,跟之前那道 Climbing Stairs 非常的相似,但是还有一些其他的限制条件,比如说一位数时不能为0,两位数不能大于 26,其十位上的数也不能为0,除去这些限制条件,跟爬梯子基本没啥区别,也勉强算特殊的斐波那契数列,当然需要用动态规划 Dynamci Programming 来解。建立一维 dp 数组,其中 dp[i] 表示s中前i个字符组成的子串的解码方法的个数,长度比输入数组长多多1,并将 dp[0] 初始化为1。现在来找状态转移方程,dp[i] 的值跟之前的状态有着千丝万缕的联系,就拿题目中的例子2来分析吧,当 i=1 时,对应s中的字符是 s[0]='2',只有一种拆分方法,就是2,注意 s[0] 一定不能为0,这样的话无法拆分。当 i=2 时,对应s中的字符是 s[1]='2',由于 s[1] 不为0,那么其可以被单独拆分出来,就可以在之前 dp[i-1] 的每种情况下都加上一个单独的2,这样 dp[i] 至少可以有跟 dp[i-1] 一样多的拆分情况,接下来还要看其能否跟前一个数字拼起来,若拼起来的两位数小于等于26,并且大于等于 10(因为两位数的高位不能是0),那么就可以在之前 dp[i-2] 的每种情况下都加上这个二位数,所以最终 dp[i] = dp[i-1] + dp[i-2],是不是发现跟斐波那契数列的性质吻合了。所以0是个很特殊的存在,若当前位置是0,则一定无法单独拆分出来,即不能加上 dp[i-1],就只能看否跟前一个数字组成大于等于 10 且小于等于 26 的数,能的话可以加上 dp[i-2],否则就只能保持为0了。具体的操作步骤是,在遍历的过程中,对每个数字首先判断其是否为0,若是则将 dp[i] 赋为0,若不是,赋上 dp[i-1] 的值,然后看数组前一位是否存在,如果存在且满足前一位是1,或者和当前位一起组成的两位数不大于 26,则当前 dp[i] 值加上 dp[i - 2]。最终返回 dp 数组的最后一个值即可,代码如下:
C++ 解法一:
class Solution {
public:
int numDecodings(string s) {
if (s.empty() || s[] == '') return ;
vector<int> dp(s.size() + , );
dp[] = ;
for (int i = ; i < dp.size(); ++i) {
dp[i] = (s[i - ] == '') ? : dp[i - ];
if (i > && (s[i - ] == '' || (s[i - ] == '' && s[i - ] <= ''))) {
dp[i] += dp[i - ];
}
}
return dp.back();
}
};
Java 解法一:
class Solution {
public int numDecodings(String s) {
if (s.isEmpty() || s.charAt() == '') return ;
int[] dp = new int[s.length() + ];
dp[] = ;
for (int i = ; i < dp.length; ++i) {
dp[i] = (s.charAt(i - ) == '') ? : dp[i - ];
if (i > && (s.charAt(i - ) == '' || (s.charAt(i - ) == '' && s.charAt(i - ) <= ''))) {
dp[i] += dp[i - ];
}
}
return dp[s.length()];
}
}
下面这种方法跟上面的方法的思路一样,只是写法略有不同:
C++ 解法二:
class Solution {
public:
int numDecodings(string s) {
if (s.empty() || s[] == '') return ;
vector<int> dp(s.size() + , );
dp[] = ;
for (int i = ; i < dp.size(); ++i) {
if (s[i - ] != '') dp[i] += dp[i - ];
if (i >= && s.substr(i - , ) <= "" && s.substr(i - , ) >= "") {
dp[i] += dp[i - ];
}
}
return dp.back();
}
};
Java 解法二:
class Solution {
public int numDecodings(String s) {
if (s.isEmpty() || s.charAt(0) == '0') return 0;
int[] dp = new int[s.length() + 1];
dp[0] = 1;
for (int i = 1; i < dp.length; ++i) {
if (s.charAt(i - 1) != '0') dp[i] += dp[i - 1];
if (i >= 2 && (s.substring(i - 2, i).compareTo("10") >= 0 && s.substring(i - 2, i).compareTo("26") <= 0)) {
dp[i] += dp[i - 2];
}
}
return dp[s.length()];
}
}
我们再来看一种空间复杂度为 O(1) 的解法,用两个变量 a, b 来分别表示 s[i-1] 和 s[i-2] 的解码方法,然后从 i=1 开始遍历,也就是字符串的第二个字符,判断如果当前字符为 '0',说明当前字符不能单独拆分出来,只能和前一个字符一起,先将 a 赋为0,然后看前面的字符,如果前面的字符是1或者2时,就可以更新 a = a + b,然后 b = a - b,其实 b 赋值为之前的 a,如果不满足这些条件的话,那么 b = a,参见代码如下:
C++ 解法三:
class Solution {
public:
int numDecodings(string s) {
if (s.empty() || s[] == '') return ;
int a = , b = , n = s.size();
for (int i = ; i < n; ++i) {
if (s[i] == '') a = ;
if (s[i - ] == '' || (s[i - ] == '' && s[i] <= '')) {
a = a + b;
b = a - b;
} else {
b = a;
}
}
return a;
}
};
Java 解法三:
class Solution {
public int numDecodings(String s) {
if (s.isEmpty() || s.charAt(0) == '0') return 0;
int a = 1, b = 1, n = s.length();
for (int i = 1; i < n; ++i) {
if (s.charAt(i) == '0') a = 0;
if (s.charAt(i - 1) == '1' || (s.charAt(i - 1) == '2' && s.charAt(i) <= '6')) {
a = a + b;
b = a - b;
} else {
b = a;
}
}
return a;
}
}
Github 同步地址:
https://github.com/grandyang/leetcode/issues/91
类似题目:
参考资料:
https://leetcode.com/problems/decode-ways/
https://leetcode.com/problems/decode-ways/discuss/30384/a-concise-dp-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Decode Ways 解码方法的更多相关文章
- [LeetCode] Decode Ways 解码方法个数、动态规划
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理) 题目描述 一条报文包含字母A-Z,使用下面的字母-数字映射进行解码 'A' -> 1 'B' -> 2 ...
- [LeetCode] 91. Decode Ways 解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- [LintCode] Decode Ways 解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- 091 Decode Ways 解码方法
包含 A-Z 的字母的消息通过以下规则编码:'A' -> 1'B' -> 2...'Z' -> 26给定一个包含数字的编码消息,请确定解码方法的总数.例如,给定消息为 "1 ...
- Leetcode91.Decode Ways解码方法
一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计算解码方法的总数. 示例 1 ...
- [leetcode]91. Decode Ways解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
- [LeetCode] decode ways 解码方式
A message containing letters fromA-Zis being encoded to numbers using the following mapping: 'A' -&g ...
- [LeetCode] Decode Ways II 解码方法之二
A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...
随机推荐
- TFS2017持续集成构建
TFS2017发布已经有几个月了,经过了几天的部署和尝试,TFS2017的功能变化真是挺大的.特别是在构建方面的变化,在产品的向导中已经声明XAML版本控制器和代理已经弃用了,并建议升级原来13和15 ...
- SparkStreaming实现Exactly-Once语义
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 译自:http://blog.cloudera.com/blog/2015/03/exactly ...
- 移动WEB开发之viewport
问题: 在codepen上写了一个响应式页面,调试的时候没有问题.结果放到网站上,在手机上打开之后竟然和在电脑中的布局是一样的. 查阅资料之后知道响应式布局应该有这样一句话:<m ...
- 使用 Windows Phone Toolkit 的 Tilt 效果
上一篇文章分享了如何使控件具有摁下的效果(在WindowsPhone中使控件具有Tilt效果),实现方式是在项目中添加新的类文件,其实,如果项目引用了Windows Phone Toolkit,那么就 ...
- .NET 开源SqlServer ORM框架 SqlSugar 3.0 API
3.1.x ,将作为3.X系统的最后一个版本,下面将会开发 全新的功能 更新列表:https://github.com/sunkaixuan/SqlSugar/releases 优点: SqlSuga ...
- ASP.NET MVC5 ModelBinder
什么是ModelBinding ASP.NET MVC中,所有的请求最终都会到达某个Controller中的某个Action并由该Action负责具体的处理和响应.为了能够正确处理请求,Action的 ...
- Cesium原理篇:5最长的一帧之影像
如果把地球比做一个人,地形就相当于这个人的骨骼,而影像就相当于这个人的外表了.之前的几个系列,我们全面的介绍了Cesium的地形内容,详见: Cesium原理篇:1最长的一帧之渲染调度 Cesium原 ...
- 【神器】vimum在浏览器中键盘操作选择、复制、粘贴,键盘党的最爱
1.下载: http://files.cnblogs.com/files/quejuwen/vimum_extension_1_56.zip 2.开源:https://github.com/philc ...
- 【前端构建】WebPack实例与前端性能优化
计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给前端优化工作带来的便利. 壹 | Fisrt 曾几 ...
- SalesForce 记录级别安全性
对象级安全性 简档 对象级安全性提供了控制 Salesforce.com 中数据的最简单方式.使用对象级安全性 您可以防止用户查看.创 建.编辑或删除特殊类型对象的任何实例 如潜在客户或业务机会.对象 ...