LeetCode第[91]题(Java):Decode Ways(解码方法数)
题目:解码方法数
难度: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.
编码过程中的问题:
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(解码方法数)的更多相关文章
- Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理)
Leetcode 91. Decode Ways 解码方法(动态规划,字符串处理) 题目描述 一条报文包含字母A-Z,使用下面的字母-数字映射进行解码 'A' -> 1 'B' -> 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 + ...
- 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 ...
- LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2
题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...
- 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 ...
- [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 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' - ...
- [leetcode]91. Decode Ways解码方法
A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...
随机推荐
- windows脚本-CMD和Batch
一.DOS,CMD和batch DOS是磁盘操作系统(英文:Disk Operating System)的缩写,是个人计算机上的一类操作系统.从1981年直到1995年的15年间,DOS在IBM PC ...
- Mac 升级 OpenSSL
[转载自 https://blog.csdn.net/focusjava/article/details/51179297 ] [升级Mac的openssl] 终端下 openssl version ...
- Elment UI的使用说明
一. Elment UI 1. 简介 Element UI是饿了么团队提供的一套基于Vue2.0的组件库,可以快速搭建网站,提高开发效率,就如同bootstrap. 2.组件分类 ElementUI ...
- MFC中存在的不属于任何类的全局函数,它们统统在函数名称开头加上Afx
MFC中存在的不属于任何类的全局函数,它们统统在函数名称开头加上Afx. 函数名称 说明 AfxWinInit 被WinMain(MFC提供)调用的一个函数,用做MFC GUI程序初始化的一部分,如果 ...
- docker——Dockerfile(一)
Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile来快速创建自定义的镜像.Dockerfile由一行行命令语句组成,并支持以#开头的注释行.一般而言,Dockerfile分 ...
- Python(线程进程3)
四 协程 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他地方,在切 ...
- [转]DNS服务器原理详解与Centos6.x下搭建DNS服务器
转自:http://blog.it985.com/8958.html DNS 数据库的记录:正解,反解, Zone 的意义 通过DNS解析过程详解这篇文章,我们知道了要想访问www.zmit.cn,最 ...
- 获取Android设备的方向,Sensor和SensorManager实现手机旋转角度
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1009/425.html 带有g-sensor的Android设备上可通过API ...
- CentOS 6.3编译安装LAMP环境笔记
转载地址:http://www.jb51.net/article/54969.htm 最近抽空在虚拟机上测试成功了LAMP各个最新版本的整合编译安装,算是把之前的博文整合精简,以下内容均在CENTOS ...
- eclipse web项目的发布路径
java Build path是编译路径设置,主要用来设置源代码的编译路径默认是default output folder Web Deployment Assembly是eclipse中的发布路径设 ...