A message containing letters from A-Z
is 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.
==============================昏割线========================
本来是自己想了半天的划分情况,修修改改,总是要遗漏情况,怼上代码,不做分析。
public static int numDecodings(String s) {
// Write your code here
if(0 == s.length()) return 0;
if(s.charAt(0)=='0') return 0;
if(s.length() == 1)
return 1;
int []dp = new int[s.length()];//记录遍历到字符串第i位置时的状态(该状态指的是编码的方法数)
dp[0] = 1;
for(int i=1;i<s.length();i++){
String temp = s.substring(i-1, i+1);// 取i位和i-1位
int num = Integer.parseInt(temp);
if(num == 0){
return 0;
}else if(1 <= num && num <= 9)
dp[i] = dp[i-1];
else if(11 <= num && num <= 19 || num >=21 && num <= 26)
dp[i] = dp[i-1] + (i - 2 >= 0 ? dp[i-2] : 1);
else if(num % 10 == 0)
if(num/10 >= 3 )
return 0;
else
dp[i] = i - 2 >= 0 ? dp[i-2] : 1;
else
dp[i] = dp[i-1];
}
return dp[s.length()-1];
}
铛铛铛铛铛铛!推出较优解:
该解法思路清晰,但是时间复杂度太高。最差情况时间复杂度为O(kn)
令f[i] 表示 在 i 位置时,解码的方法数。显然,f[i] 可由之前的2个状态得出。
① 选择单独解码第i个位置,此时,f[i] = f[i-1]
② 选择解码i 和i - 1 位置, 此时, f[i] = f[i - 2]
class Solution
{
public:
int decodeOne(char one) {
return (one == '0') ? 0 : 1; // 判断单个字符能否解码
}
int decodeTwo(char one, char two) {
if( (one == '1') || (one == '2' && two <= '6') ) // 判断双字符的解码情况
return 1;
else
return 0;
}
int fun(string s, int i) {
if(i == 0 ) return decodeOne(s[0]); // 只有1个字符,直接判断
if(i == 1) return ( decodeOne(s[0]) & decodeOne(s[1]) ) + decodeTwo(s[0], s[1]); // 2个字符, 先单个, 再2个
if(i >= 2) {
int sum = 0;
if(decodeOne(s[i])) sum += fun(s, i-1);
if(decodeTwo(s[i-1], s[i]) ) sum += fun(s, i-2);
return sum;
}
}
int numDecodings(string s)
{
if(s.size() == 0 || s[0] == '0') return 0;
return fun(s, s.size() - 1);
}
};