LeetCode | 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.

题目解析:

一开始想着i和i+1能够匹配,count++(方案错误,1212的话,结果是4,由于还有12 1 2  12 12,也就是前后两个有乘积)。

方案不同,考虑到乘积又进行处理,进行动态规划,建立二维数组。但简单乘积还不行,还有可能分界点k和k+1也匹配,就需要额外加上res[i..k-1] * res[k+2…j]。方案又不行……

我们还是要尝试着去举例子,举例子的过程中就会发现一定的规律:

123123进行译码:

1 2 3 1 2 3—–各自单独,1种情况

12 3 1 2 3

12 3 12 3

12 3 1 23——-以12开头后面有三个

1 23 1 2 3

1 23 12 3

1 23 1 23——以23结合后面也有三个

1 2 3 12 3

1 2 3 1 23—–后面三个数处理,有两个

从这里可以看出来,12和23结合的时候,后面的情况是重复的,还是用动态规划,不过这里的动态规划就是一维的了。简单和邻近值的结合。

从这里我们看到第i个数据,和i+1…n的数据个数有关系,那么从后往前求么?这样也是可以的。但没有必要非倒着求,由于数据是对称的,可以转换成正向递增求解。

定义F[i]表示S的子串S[0..i]的decode ways。

假设我们已经知道了F[0]~F[i],现在需要求解F[i+1]。

先不考虑边界,就考虑一般情况:

1.S[i+1] == ‘0’,如果S[i]为’1’或者’2’,F[i+1] = F[i],否则无解;

2.如果S[i]为’1’,F[i+1] = F[i] + F[i-1](例如”xxxxxx118″,可以是”xxxxxx11″ + “8”,也可以是”xxxxxx1″ + “18”);

3.如果S[i]为’2’,当S[i+1] <= ‘6’时,F[i+1] = F[i] + F[i-1] (最大的Z为”26″,”27″”28″”29″不存在),当S[i+1] > ‘6’时,F[i+1] = F[i] (例如”xxxxxx28″,只能是”xxxxxx2″ + “8”)。

代码如下:

class Solution {
public:
    int numDecodings(string s) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if (s.empty()) {
            return 0;
        }
        int length = s.length();   
        int f[length];
        memset(f, 0, sizeof(int) * length);
        for (int i = 0; i < length; i++) {
            if (s[i] < '0' || s[i] > '9') {
                return 0;
            }
            else if (s[i] == '0') {
                if (i == 0 || s[i - 1] == '0' || s[i - 1] > '2') {
                    return 0;
                }
                else {
                    f[i] = i > 1 ? f[i - 2] : 1;
                }
            }
            else {
                if (i > 0 && (s[i - 1] == '1' || s[i - 1] == '2' && s[i] <= '6')) {
                    f[i] = (i > 0 ? f[i - 1] : 1) + (i > 1 ? f[i - 2] : 1);
                }    
                else {
                    f[i] = i > 0 ? f[i - 1] : 1;
                }
            }
        }
        return f[length - 1];
    }
};

点赞