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.
Analysis:
The key to this problem is : num(current) = num(current-1) + num(current-2).
Be careful with the conditions of above equation:
if the current char =='0'
if the current char and previous char >26
if the previous char =='0'
This can be think as a simple DP problem, res[i]= res[i-1] if s[i] is valid + res[i-2] if s[i-1:i] is valid.
Java
public int numDecodings(String s) {
if(s.length()<=0) return 0;
int len = s.length();
int res[] = new int[len];
if(s.charAt(0)!='0') res[0] = 1;
if(len==1) return res[0];
if(check(s.substring(0, 2))) res[1]++;
if(s.charAt(0)!='0'&&s.charAt(1)!='0') res[1]++;
//DP
for(int i=2;i<len;i++){
if(s.charAt(i)!='0')res[i] +=res[i-1];
if(check(s.substring(i-1, i+1)))
res[i]+=res[i-2];
}
return res[len-1];
}
public boolean check(String string){
if(string.length()==0) return false;
if(string.charAt(0)=='0') return false;
if(string.length()==2){
if(string.charAt(0)>'2'||(string.charAt(0)=='2'&&string.charAt(1)>'6'))
return false;
}
return true;
}
c++
int check(char one){
return (one != '0') ? 1:0;
}
int check(char one, char two){
return (one =='1' || (one=='2'&& two<='6'))?1:0;
}
int numDecodings(string s) {
if(s.empty() || s[0]=='0') return 0;
if(s.size()==1) return check(s[0]);
int fn=0, fn_1 = 0,fn_2 = 1;
fn_1 = (check(s[0])*check(s[1]))+check(s[0],s[1]);
for(int i=2;i<s.size();i++){
if(check(s[i])) fn+=fn_1;
if(check(s[i-1],s[i])) fn+=fn_2;
if(fn == 0)
return 0;
fn_2 = fn_1;
fn_1 = fn;
fn = 0;
}
return fn_1;
}