Answer:
DP method.
Transformation function :
Count[i] = Count[i-1], if S[i-1] is a valid char
or = Count[i-1]+ Count[i-2], if S[i-1] and S[i-2] together is still a valid char.
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<iostream>
#include<string>
using namespace std;
int check(char one){
return (one != '0') ? 1 : 0;
}
int check2(char one, char two){
return (one == '1' || (one == '2' && two <= '6')) ? 1 : 0;
}
int numDecode(string s){
int len = s.length();
if(s.empty()) return 0;
vector<int> f(len,0);
//Edge cases.
f[0] = check(s[0]);
if(f[0] == 0) return 0;
if(check(s[1]) && check(s[0]) && check2(s[0],s[1])){
f[1] = 1+ f[0];
}
else if(check(s[1])){
f[1] = f[0];
}
if(len == 1) return f[0];
if(len == 2) return f[1];
int i= 2;
while(i<len){ //len >= 3.Recursion cases.
if(check(s[i]) && check(s[i-1]) && check2(s[i],s[i-1])){
f[i] = f[i-1] + f[i-2];
}
else if(check(s[i])){
f[i] = f[i-1];
}
else{ //!check(s[i])
return 0;
}
++i;
}
return f[len-1];
}
/*****Similar, but Better, O(1) space *******/
/*
int numDecode(string s){
int len = s.length();
if(s.empty()) return 0;
if(!check(s[0])) return 0;
int fn=0, fn_1=0, fn_2=1;
//Edge cases.
if(check(s[1]) && check(s[0]) && check2(s[0],s[1])){
fn_1 = 1 + fn_2;
}
else if(check(s[1])){
fn_1 = fn_2;
}
if(len == 1) return fn_2;
if(len == 2) return fn_1;
int i= 2;
while(i<len){ //len >= 3.Recursion cases.
if(check(s[i]) && check(s[i-1]) && check2(s[i],s[i-1])){
fn = fn_1 + fn_2;
}
else if(check(s[i])){
fn = fn_1;
}
else{ //!check(s[i])
return 0;
}
fn_2 = fn_1;
fn_1 = fn;
++i;
}
return fn_1;
}
*/
int main(){
int res = numDecode("1212");
cout << res;
getchar();
return 0;
}
No comments:
Post a Comment