题目:解码方法数

难度:Medium

题目内容

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.

翻译

一个包含A-Z字母的消息被编码成数字,使用以下映射:

“A” - > 1

“B”- > 2

……

“Z”- > 26

给定一个包含数字的非空字符串,确定解码它的总方法数。

我的思路:一开始想用递归但是边界问题太多,就放弃了。

      single 从0开始(每个数组单独解码),count从1开始,如果s[i-1]s[i]二者组成的数字在(0,26 ] 范围内,那就count+;

      且遇见0的时候,一开始的单独编码就不存在了,且少了一次组合的机会,例如【110】 中【11】和【0】不能组合

        所以此时 single = 0;count - 1

我的代码

     public int numDecodings(String s) {
if (s.isEmpty() || s.charAt(0) == '0')
return 0; int count = 0;
int single = 1;
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == '0'){
count = s.length() > 2 ? count-1 : count;
single = 0;
}
int x = Integer.parseInt(s.substring(i-1, i+1));
if ( x<= 26 && x > 0) {
count += 1;
}
}
return (count + single) > 0 ? (count + single) : 0;
}

结果:214 / 258 test cases passed.

Input:"1212"
Output:4
Expected:5

编码过程中的问题

1、最初 single 和 count 没有分开计算;

2、第9行,当只有两个的时候,此时count 不需要 -1 ,例如【10】;

3、这个思路还是有问题的,例如【1212】中少计算了【12】【12】这个组合

答案代码

 public class Solution {
public int numDecodings(String s) {
int n = s.length();
if (n == 0) return 0; int[] memo = new int[n+1];
memo[n] = 1;
memo[n-1] = s.charAt(n-1) != '0' ? 1 : 0; for (int i = n - 2; i >= 0; i--)
if (s.charAt(i) == '0') continue;
else memo[i] = (Integer.parseInt(s.substring(i,i+2))<=26) ? memo[i+1]+memo[i+2] : memo[i+1]; return memo[0];
}
}

答案思路

假设所有的数字都有效,且左右两两相邻数之间也有效(1到26),那么有如下规律

   numDecodings(s) = numDecodings(s.substring(1)) + numDecodings(s.substring(2)) --------------------------------------------------式(1)

规律显而易见,斐波那契数列。不过是反过来的(从字符串后面往前)

当然,那只是假设,也要考虑特殊情况:

【使用一个数组(大小为len+1)从后往前记录对应的数字“出现”后解码数的增量

1、当前指针所指字符为0

  此时此字符无法解码,所以式(1)中的前者就只能为0,后者也为0

  例如【023】,substring(1)——【0】|【23】,截掉的【0】不能解析,所以此组合无效

         substring(2)——【02】|【3】,截掉的【02】不能解析,所以此组合无效

  所以0数字出现后,解码数的增量为0。

2、当前字符的值是有效的(大于0),但是当前字符与右边字符组合的数字无效(大于26)

  相当于式(1)中的后者=0

  例如【3212】,substring(1)——【3】|【212】,截掉的【3】能解析,所以其值为【212】的解码数

         substring(2)——【32】|【12】,截掉的【32】不能解析,所以此组合无效\

递归实现:

     public int numDecodings(String s) {
if (s.isEmpty()) {
return 1;
} if (s.charAt(0) == '0') {
return 0;
} if (s.length() == 1)
return 1; int sub1 = numDecodings(s.substring(1));
int sub2 = 0; if (Integer.parseInt(s.substring(0,2)) <= 26) {
sub2 = numDecodings(s.substring(2));
}
return sub1 + sub2;
}

此方法会在最后几个用例(很长)运行超时。

所以答案采用了迭代的方式进行。

优化:既然是斐波纳数列,那么就能使用双值迭代的方式取代用一个数组进行记录。

     public int numDecodings(String s) {
if (s.isEmpty() || s.charAt(0) == '0') {
return 0;
}
int sub1 = 1;
int sub2 = 1;
for (int i = s.length() - 2; i > -1; i--) {
if (s.charAt(i+1) == '0') {
sub1 = 0;
}
if (Integer.parseInt(s.substring(i,i+2)) <= 26) {
sub1 = sub1 + sub2;
sub2 = sub1 - sub2;
} else {
sub2 = sub1;
}
}
return sub1;
}

第11行其实还可以使用字符进行判断以降低时间和空间复杂度:

   s.charAt(i) == '1' || s.charAt(i) == '2' && s.charAt(i+1) - '0' <= 6

LeetCode第[91]题(Java):Decode Ways(解码方法数)的更多相关文章

  1. Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)

    Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理) 题目描述 一条报文包含字母A-Z,使用下面的字母-数字映射进行解码 'A' -> 1 'B' -> 2 ...

  2. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  3. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  4. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  5. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  6. [LeetCode] 91. Decode Ways 解码方法

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  7. [LeetCode] Decode Ways 解码方法

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  8. [LintCode] Decode Ways 解码方法

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  9. [leetcode]91. Decode Ways解码方法

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

随机推荐

  1. 华为交换机VRP用户界面配置及Telnet登录实验

    user privilege level level 设置使用以上用户界面登录后的用户级别 5 acl acl-number { inbound | outbound } (可选)在用户界面上应用AC ...

  2. C#建WindowForm调用R可视化

    众所周知R软件功能非常强大,可以很好的进行各类统计,并能输出图形.下面介绍一种R语言和C#进行通信的方法,并将R绘图结果显示到WinForm UI界面上的方法,文中介绍的很详细,需要的朋友可以参考下. ...

  3. zabbix 添加 微信、邮件 媒介详解

    1:zabbix 添加 微信.邮件 媒介.  1.2:发送告警邮件         1:一次完整的监控流程可以简单描述为:         Host Groups (设备组) ->Hosts ( ...

  4. matlab实现MSER(最大极值稳定区域)来进行文本定位

    一.自然场景文本定位综述   场景图像中文本占据的范围一般都较小,图像中存在着大范围的非文本区域.因此,场景图像文本定位作为一个独立步骤越来越受到重视.这包括从最先的CD和杂志封面文本定位到智能交通系 ...

  5. PAT 1051 Pop Sequence[栈][难]

    1051 Pop Sequence (25 分) Given a stack which can keep M numbers at most. Push N numbers in the order ...

  6. TensorFlow学习笔记(三)MNIST数字识别问题

    一.MNSIT数据处理 MNSIT是一个非常有名的手写体数字识别数据集.包含60000张训练图片,10000张测试图片.每张图片是28X28的数字. TonserFlow提供了一个类来处理 MNSIT ...

  7. js 根据json数组中n个字段排序

    function compare(name, minor) { return function (o, p) { var a, b; if (o && p && typ ...

  8. 百度NLP二面

    实验室项目:1.实验室方向 2.用两分钟介绍自己的项目,创新点在哪里 个人项目:     1.自己实现的贝叶斯分类器,目的,怎么做的 2.怎么计算各个分类的先验.(因为我使用的训练预料是每个分类10篇 ...

  9. HMM,MEMM,CRF模型的比较

    本文参考自:http://blog.csdn.net/happyzhouxiaopei/article/details/7960876 这三个模型都可以用来做序列标注模型.但是其各自有自身的特点,HM ...

  10. To keep up-to-date with Latest Jordans 2016

    The Latest Jordans 2016 will feature cement speckling because the base, Reflect Silver accents, a a ...