【leetcode】Decode Ways(medium)
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.
做了好久才AC,主要是脑子不清楚,思路不清晰。虽然最后想通了但花了一整个下午。
思路:
f(n) 表示,从第n个字符起的字符串可以排列的方式
从后向前判断,如果该数字是0,则只有0种方式;如果数字非0,则该位数字单独解码,方式有f(n - 1)种。如果该数字可以和它后面的数字一起解码,则该数字和他后面的数字一起,方式再加上f(n-2)种。
class Solution { public: int numDecodings(string s) { int iway[2] = {1,1}; int slen = s.length(); if(slen <= 0) return 0; iway[0] = (s[slen - 1] == '0') ? 0 : 1; for(int i = s.length() - 2; i >= 0; i--) { int curWays = 0; if(s[i] != '0') { curWays += iway[0]; } int num = (s[i] - '0') * 10 + (s[i + 1] - '0'); if(10 <= num && num <= 26) { curWays += iway[1]; } iway[1] = iway[0]; iway[0] = curWays; } return iway[0]; } };
大神更加简洁的代码,思路差不多,就是从前向后判断的:
int numDecodings(string s) { // empty string or leading zero means no way if (!s.size() || s.front() == '0') return 0; // r1 and r2 store ways of the last and the last of the last int r1 = 1, r2 = 1; for (int i = 1; i < s.size(); i++) { // zero voids ways of the last because zero cannot be used separately if (s[i] == '0') r1 = 0; // possible two-digit letter, so new r1 is sum of both while new r2 is the old r1 if (s[i - 1] == '1' || s[i - 1] == '2' && s[i] <= '6') { r1 = r2 + r1; r2 = r1 - r2; } // one-digit letter, no new way added else { r2 = r1; } } return r1; }