Decode Ways
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.
分析:比较容易想到的方法是递归,decode有两种方式,一种是对当前一个数字decode,另一种是如果当前开始的两个数字小于等于26我们可以对开始的两个数字decode,然后再递归的对剩下的数字序列decode。但这种方法超时,代码如下:
class Solution { public: int numDecodings(string s) { return getNumDecodings(s, 0); } int getNumDecodings(string s, int start){ if(start == s.length()) return 0; if(start == s.length()-1) return 1; return (atoi(s.substr(start,2).c_str()) <= 26)?getNumDecodings(s,start+1) + getNumDecodings(s,start+2):getNumDecodings(s,start+1); } };
动态规划的方法解,record[i]表示s[0:i-1]的decoding ways,初始化record[0] = 1。递推公式如下:
如果s[i-1]不为'0',因为没有字母与'0'对应,record[i] += record[i-1]。
如果i > 1并且s[i-2]不为'0'并且s[i-2:i-1]对应的数字小于等于26,因为没有字母对应'0x'的形式或者大于26,record[i] += record[i-2]。
时间复杂度为O(n),空间复杂度为O(n)。代码如下:
1 class Solution { 2 public: 3 int numDecodings(string s) { 4 int n = s.length(); 5 if(n == 0) return 0; 6 vector<int> record(n+1, 0); 7 record[0] = 1; 8 for(int i = 1; i < n + 1; i++){ 9 if(s[i-1] != '0') record[i] += record[i-1]; 10 if(i > 1 && s[i-2] != '0' && atoi(s.substr(i-2,2).c_str()) <= 26) 11 record[i] += record[i-2]; 12 } 13 return record[n]; 14 } 15 };