題目表述:
這道題目和斐波那契數列以及跳臺階問題十分相似。
斐波那契數列:0、1、1、2、3、5, 8、13、21、34 ……?
leetcode跳臺階問題:1、1、2、3、5, 8、13、21、34.......
這類題目的特點都是第N項的結果等于前兩項的和。
但是解密數字不一樣,前面幾道題目都是無條件的,直接把前兩項的和相加就可以了,這個題目不能直接相加,而是需要判斷,然后再進行運算。
假設f(i)代表i個數字之前的解,那么新加入一個數字后,需要考慮兩種情況,第一種情況這個數字只能單獨翻譯成一個字母,這種情況下加了也白加,f(i+1) = f(i); 第二種情況就是這個數字還能和第i個數字聯合起來翻譯成一個字母,比如10~25之間的兩位數都可以被翻譯成字母。那這種情況下f(i) = f(i-1) + f(i-2)。事實上因為這個地方無論是個位數還是兩位數,最多只能翻譯成1種字母,如果可以翻譯成多種字母,那么就成了f(i) = g(i) * f(i-1) + g(i-1, i) * f(i-2)。
所以有公式f(i) = f(i-1) +f(i-2) 或者 f(i) = f(i-1)。按道理來說,i是大于等于2的,但是這里有個問題
f(0)=1,這是必然的,但是f(1)是1還是2就難說了。所以還要計算f(1) = f(0) + f(-1)
在斐波那契數列和登臺階的問題中,f(-1)都被設定成了0,但是這里設定成0顯然是不合適的。按照f(1)的取值和計算公式應該設定成1
代碼:
class Solution {
public:int crackNumber(int ciphertext) {if(ciphertext<10)return 1;string src = to_string(ciphertext);// f(i) = g(i) * f(i-1) + g(i-2) * f(i-2)// f(i) = f(i-1) + f(i-2), i>=2// f(2) = f(1) + f(0)// f(1) = f(0) + f(-1)// ? = 1 + ?//. r = q + pint r, p, q;r = 0;p = 1;q = 1;for(int i=1; i<src.size(); ++i){auto pre = src.substr(i-1, 2);if(pre>="10" && pre<="25"){r = p+q;}else{r = q;}p = q;q = r;} return r;}};