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.
遇到字符串相关的题目,首先考虑动态规划的方法。
方法一:建立一个dp数组,dp[i]表示字符串0~i-1位的解码方法,先考虑s[i-1]组成一个数字的情况,如果s[i]!=0,则dp[i]+=dp[i-1]。再考虑s[i-2]和s[i-1]组成两位数字的情况,则如果i>=2且s[i-2]和s[i-1]在1~26内,dp[i]+=dp[i-2]。最后输出dp[n](n为字符串长度)。
class Solution { public: int numDecodings(string s) { if (s.empty()) return 0; vector<int> dp(s.size() + 1, 0); dp[0] = 1; for (int i = 1; i < dp.size(); ++i) { if (s[i - 1] != '0') dp[i] += dp[i - 1]; if (i >= 2 && s.substr(i - 2, 2) <= "26" && s.substr(i - 2, 2) >= "10") { dp[i] += dp[i - 2]; } } return dp.back(); } };
方法二:
可将方法一改进为O(1)复杂度,用c1代表循环到s[i]时,0~i-1解码的数量,c2代表0~i-2解码的数量,其他如方法一。
class Solution { public: int numDecodings(string s) { if(s.empty() || s.front() == '0') return 0; int c1=1,c2=1; for(int i=1;i<s.size();i++) { int temp=0; if(s[i]!='0') temp+=c1; if((s[i-1]=='2' && s[i]<='6')|| s[i-1]=='1') temp+=c2; c2=c1; c1=temp; } return c1; } };