91. Decode Ways
2016-07-05 11:46
344 查看
题目:
A message containing letters from
mapping:
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message
2) or
The number of ways decoding
题意:
给你一串数字,解码成英文字母。
思路一:
动态规划(DP),定义S数组,S[i]表示:字符串S[0...i-1]可以有S[i]中解码方式。一般情况下:
1、如果S[i] == '0',如果S[i-1]存在且为'1'或者'2',F[i] = F[i-1],否则无解;
2、如果S[i] != '0'
如果S[i-1]=='1',F[i] = F[i-1] + F[i-2](例如"xxxxxx11",可以是"xxxxxx11",也可以是"xxxxxx1" + "1“);
如果S[i-1]=='2',当S[i] <= '6'时,F[i] = F[i-1] + F[i-2] (最大的Z为"26","27""28""29"不存在),当S[i] > '6'时,F[i] = F[i-1] (例如"xxxxxx28",只能是"xxxxxx2" + "8")。
代码:2ms
public class Solution {
public int numDecodings(String s) {
if (s == null || s.length() == 0)
return 0;
int[] S = new int[s.length()];
for (int i=0; i<s.length(); i++) {
if (s.charAt(i) == '0') {
if (i == 0 || s.charAt(i-1) == '0' || s.charAt(i-1)>'2') //表示超出编码范围
return 0;
else
S[i] = i > 1 ? S[i-2] : 1;
} else {
if (i > 0 && (s.charAt(i-1)=='1' || s.charAt(i-1)=='2' && s.charAt(i)<'7')) {
S[i] = S[i-1] + (i>1 ? S[i-2] : 1);
} else {
S[i] = i > 0 ? S[i-1] : 1;
}
}
}
return S[s.length()-1];
}
}
思路二:转载地址:https://segmentfault.com/a/1190000003813921
解码是有规律的,所以我们可以尝试动态规划。假设数组dp[i]表示从头到字符串的第i位,一共有多少种解码方法的话,那么如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们是在第i-2位的解码方法上继续解码。如果字符串的第i-1位和第i位不能组成有效二位数字,而且第i位不是0的话,说明我们是在第i-1位的解码方法上继续解码。所以,如果两个条件都符合,则dp[i]=dp[i-1]+dp[i-2],否则dp[i]=dp[i-1]。注意:如果出现无法被两位数接纳的0,则无法解码,我们可以在一开始就判断,并将其初始化为0,这样后面的相加永远都是加0。
代码:6ms
public class Solution {
public int numDecodings(String s) {
if (s.length() == 0)
return s.length();
int[] dp = new int[s.length() + 1];
dp[0] = 1; // 初始化第一种解码方式
dp[1] = s.charAt(0) == '0' ? 0 : 1; // 如果第一位是0,则无法解码
for (int i=2; i<=s.length(); i++) {
// 如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们可以在第i-2位的解码方法上继续解码
if (Integer.parseInt(s.substring(i-2, i)) <= 26 && Integer.parseInt(s.substring(i-2, i)) >= 10) {
dp[i] += dp[i-2];
}
// 如果字符串的第i-1位和第i位不能组成有效二位数字,在第i-1位的解码方法上继续解码
if (Integer.parseInt(s.substring(i-1, i)) != 0) {
dp[i] += dp[i-1];
}
}
return dp[s.length()];
}
}
另一种写法:6ms
public class Solution {
public int numDecodings(String s) {
int n = s.length();
if (n == 0) return 0;
int[] memo = new int[n+1];
memo
= 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];
}
}
A message containing letters from
A-Zis being encoded to numbers using the following
mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given an encoded message containing digits, determine the total number of ways to decode it.
For example,
Given encoded message
"12", it could be decoded as
"AB"(1
2) or
"L"(12).
The number of ways decoding
"12"is 2.
题意:
给你一串数字,解码成英文字母。
思路一:
动态规划(DP),定义S数组,S[i]表示:字符串S[0...i-1]可以有S[i]中解码方式。一般情况下:
1、如果S[i] == '0',如果S[i-1]存在且为'1'或者'2',F[i] = F[i-1],否则无解;
2、如果S[i] != '0'
如果S[i-1]=='1',F[i] = F[i-1] + F[i-2](例如"xxxxxx11",可以是"xxxxxx11",也可以是"xxxxxx1" + "1“);
如果S[i-1]=='2',当S[i] <= '6'时,F[i] = F[i-1] + F[i-2] (最大的Z为"26","27""28""29"不存在),当S[i] > '6'时,F[i] = F[i-1] (例如"xxxxxx28",只能是"xxxxxx2" + "8")。
代码:2ms
public class Solution {
public int numDecodings(String s) {
if (s == null || s.length() == 0)
return 0;
int[] S = new int[s.length()];
for (int i=0; i<s.length(); i++) {
if (s.charAt(i) == '0') {
if (i == 0 || s.charAt(i-1) == '0' || s.charAt(i-1)>'2') //表示超出编码范围
return 0;
else
S[i] = i > 1 ? S[i-2] : 1;
} else {
if (i > 0 && (s.charAt(i-1)=='1' || s.charAt(i-1)=='2' && s.charAt(i)<'7')) {
S[i] = S[i-1] + (i>1 ? S[i-2] : 1);
} else {
S[i] = i > 0 ? S[i-1] : 1;
}
}
}
return S[s.length()-1];
}
}
思路二:转载地址:https://segmentfault.com/a/1190000003813921
解码是有规律的,所以我们可以尝试动态规划。假设数组dp[i]表示从头到字符串的第i位,一共有多少种解码方法的话,那么如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们是在第i-2位的解码方法上继续解码。如果字符串的第i-1位和第i位不能组成有效二位数字,而且第i位不是0的话,说明我们是在第i-1位的解码方法上继续解码。所以,如果两个条件都符合,则dp[i]=dp[i-1]+dp[i-2],否则dp[i]=dp[i-1]。注意:如果出现无法被两位数接纳的0,则无法解码,我们可以在一开始就判断,并将其初始化为0,这样后面的相加永远都是加0。
代码:6ms
public class Solution {
public int numDecodings(String s) {
if (s.length() == 0)
return s.length();
int[] dp = new int[s.length() + 1];
dp[0] = 1; // 初始化第一种解码方式
dp[1] = s.charAt(0) == '0' ? 0 : 1; // 如果第一位是0,则无法解码
for (int i=2; i<=s.length(); i++) {
// 如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们可以在第i-2位的解码方法上继续解码
if (Integer.parseInt(s.substring(i-2, i)) <= 26 && Integer.parseInt(s.substring(i-2, i)) >= 10) {
dp[i] += dp[i-2];
}
// 如果字符串的第i-1位和第i位不能组成有效二位数字,在第i-1位的解码方法上继续解码
if (Integer.parseInt(s.substring(i-1, i)) != 0) {
dp[i] += dp[i-1];
}
}
return dp[s.length()];
}
}
另一种写法:6ms
public class Solution {
public int numDecodings(String s) {
int n = s.length();
if (n == 0) return 0;
int[] memo = new int[n+1];
memo
= 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];
}
}
相关文章推荐
- Android APP中清除缓存功能详解
- ansible安装以及配置
- iOS中使用UITextView时候的一些小技巧
- [android编程学习日记1]搞硬件的,学习android初学心得,一下子豁然开朗许多
- java使用freemarker模版下载成Excel文件
- 【2016 Esri全球用户大会主题看点】I Can Find You—GeoAnalytics Server大数据分析工具
- 创建型--工厂方法模式
- Linux_tar命令_linux压缩与解压缩
- C++中引用(&)的用法和应用实例
- 理解水平扩展和垂直扩展
- 图片鉴黄服务提供商
- Material Design学习笔记
- 钩子函数大全(2)
- openwebkitsharp 打不开本地网页文件
- Python类和实例
- Helpers\Assets
- alloc、init你弄懂50%了吗?
- 浏览器内核大揭秘
- linux下Scala的安装
- Redis 配置文件详解