A message containing letters from A-Z
is being encoded to numbers using the following mapping:git
'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).app
The number of ways decoding "12"
is 2.spa
解題思路:code
使用動態規劃的思想。blog
(一)字符串
初始想法能夠創建一個數組,數組的每一位保存對應字符串的每一位可能出現的解碼方式,例如:string
字符串321321312;其對應的截止到每一位可能存在的解碼方式種類爲:it
3 - 1種class
32 - 1種
321 - 2種
3213 - 3種
32132 - 5種
....
因此獲得解碼方式數組爲:
原字符串S: 3 2 1 3 2 1 3 1 2
解碼種類數組A: 1 1 2 3 5 8 16 16 32
發現:
(1)若是當前字符能夠和上一個字符組成二元字符,例如'1'和'2'組成'12',那麼A[i] = A[i-1] + A[i-2];
很好理解,等於將'1' '2'分開的解碼種類與將'12'合起來的解碼種類之和;
(2)若是當前字符不能和上一個字符組成二元字符,那麼A[i] = A[i-1];
(二)
所以,進一步的思路是,不須要創建一個數組,只須要保存i-2和i-1的解碼種類數就能夠了,分別用r1和r2表示;
若是當前字符能夠組成二元字符,那麼當前字符的次數 = r1 + r2;
若是不能,當前字符次數 = r1;
(三)
進一步發現,只用r1和r2兩個變量就夠了
(1)每次遇到能夠組成二元字符的字符時,就更新r1,使r2等於舊的r1:
r1= r1 + r2;
r2 = r1;
(2)當不能組成二元字符時,r1不變,更新r2爲r1;
(3)最終返回r1;
注意:
若是當前字符是'0',若是將'0'單獨算,則不能產生任何解碼數,即解碼數爲0;
代碼:
1 int numDecodings(string s) { 2 if (!s.size() || s.front() == '0') return 0; 3 int r1 = 1, r2 = 1; 4 5 for (int i = 1; i < s.size(); i++) { 6 if (s[i] == '0') r1 = 0; 7 8 if (s[i - 1] == '1' || s[i - 1] == '2' && s[i] <= '6') { 9 r1 = r2 + r1; 10 r2 = r1 - r2; 11 } else { 12 r2 = r1; 13 } 14 } 15 16 return r1; 17 }