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 };

 

posted on 2014-10-22 12:15  Ryan-Xing  阅读(133)  评论(0)    收藏  举报