1...26
给一个字符串有多少种组成方法。。
开始觉得嘛。。。
这个呢。。就是看一位一位的看嘛。。。
如果新加入的这位可以和前面的组成1..26 之间的数,那么就等于前面那些位能组成的方法+除去前两位组成的方法
f[i]表示从头到弟i位有多少种方法
那么就是
i如果是能和i-1构成 1..26...
那么f[i] = f[i-1] + f[i-2]
意思就是i单独的一种方法,和与i-1一起构成两位的方法。
如果不能f[i] = f[i-1]
到此,感觉就做完啦。
不过。。。不过。。。我没有考虑0啊。。。
有0要特殊处理。。。
首先第一位肯定不能有0 , 也不能有连续的0
10,20这种只f[i] = f[i-2]
00,30,40...等都是非法的。。。。
class Solution { public: int numDecodings(string s) { if (s == "") return 0; if (s[0] == '0') return 0; int size = s.size(); if(size == 1) return 1; vector<int> f(size , 0); f[0] = 1; f[1] = 2; // cout << s[1] << " " << s[0] <<endl; //cout << "s[1] = " << s[1] <<endl; if(s[1] == '0' && (s[0] == '1' || s[0] == '2')) f[1] = 1; if(s[1] == '0' && !(s[0] == '1' || s[0] == '2')) return 0; if(s[0] == '2' && (s[1] > '6')) f[1] = 1; if(s[0] > '2') f[1] = 1; //cout << f[1] <<endl; //cout << "coming" <<endl; for(int i = 2 ; i < size ; i++){ f[i] = f[i - 1]; if(s[i] == '0' && (s[i-1] == '1' || s[i - 1] == '2')) {f[i] = f[i-2];continue;} if(s[i] == '0' && !(s[i-1] == '1' || s[i - 1] == '2')) return 0; if(s[i-1] == '1') f[i] += f[i-2]; if(s[i-1] == '2' && (s[i] >= '1' && s[i] <= '6')) f[i] += f[i-2]; } return f[size - 1]; } };
by 1957