首页 > 其他 > 详细

LeetCode Decode Ways

时间:2014-03-14 18:06:36      阅读:312      评论:0      收藏:0      [点我收藏+]
bubuko.com,布布扣
class Solution {
private:
    // used by dfs only
    int* memo;
    const char* str;
public:
    // 1 .dfs using a memo
    int _numDecodings(string s) {
        str = s.c_str();
        memo = new int[s.length()];
        memset(memo, -1, sizeof(int) * s.length());
        
        int ways = dfs(str, str + s.length() - 1);
        
        delete[] memo;
        return ways;
    }
    
    // 2. dynamic programming
    int numDecodings(string s) {
        const char* str = s.c_str();
        int len = s.length();
        if (len == 0) return 0;
        int ways = 0;
        
        int (*dp)[2] = new int[len + 2][2];
        dp[0][0] = dp[0][1] = dp[1][1] = 0;
        dp[1][0] = 1;
        
        for (int i=0; i<len; i++) {
            int d1 = str[i] - 0, d2 = 0;
            int prev = dp[i+1][0] + dp[i][1];
            bool d1_valid = (d1>=1 && d1<=26);
            dp[i+2][0] = d1_valid ? prev : 0;
            
            if (i+1 < len && d1_valid) {
                d2 = d1 * 10 + str[i+1] - 0;
                dp[i+2][1] = (d2 >=1 && d2 <= 26) ? prev : 0;
            } else {
                dp[i+2][1] = 0;
            }
        }
        ways = dp[len - 1 + 2][0] + dp[len - 2 + 2][1];
        delete[] dp;
        return ways;
    }
    
    int dfs(const char* cur, const char* last) {
        if (cur > last) return 0;
        int d1 = *cur - 0;
        if (d1 < 1 || d1 > 26) return 0;
        int midx = cur - str;
        if (memo[midx] != -1) return memo[midx];
        
        
        int d2 = 0;
        
        if (cur != last) {
            d2 = d1*10 + *(cur+1)-0;
        }
        int c1 = 0, c2 = 0;
        if (cur == last) {       // last one digit
            c1 = 1;
        } else {                        // other cases
            c1 = dfs(cur + 1, last);
        }
        if (d2 > 26) {                  // invalid
            c2 = 0;
        } else if (cur + 1 ==  last) {  // last two digit
            c2 = 1;
        } else {                        // other cases
            c2 = dfs(cur + 2, last);
        }
        
        memo[midx] = c1 + c2;
        return memo[midx];
    }
};
bubuko.com,布布扣

1. 首先可以用dfs进行穷举搜索,但这跟刚开始学编程语言那会儿用递归函数计算斐波拉契数列一样有很多步重复,因此可以使用一个数组来存储这些已有的计算结果

2. 往往能够用方式1进行解决的问题可以采用动态规划解决,那就用呗!

 

用dp[i+2][0]表示从字符串开始到第i-1个字符(i从0开始到str.len-1),且把第i位作为一个字母看待时的合法的可能情况总数。

用dp[i+2][1]表示从字符串开始到第i-1个字符(i从0开始),且把第i位,第i+1位合起来作为一个字母看待时合法的可能情况总数。

而前面的[0, i-1]个字符可以通过子串[0,i-2] 连接[i-1](将一个数字作为字母代码看待) 或者 [0, i-3] 连接 [i-2, i-1](将两个数字作为字母代码看待)得到。

而这两种情况的数目为dp[i-1 + 2][0] + dp[i-2 + 2][1]

 

现在只要判断第i作为一个字母的代码是否合法和[i,i+1]位合起来作为一个字母的代码是否合法了,如果合法则情况数目为dp[i-1 + 2][0] + dp[i-2 + 2][1],如果不合法则置为零。

 

根据算法导论上的说法,如果一个问题的解可以用它的最优子问题解表示那么就可以采用动态规划去解决。memo数组中存储的其实就是一些问题的最优子问题解,

dp数组中存储的也是这样。

LeetCode Decode Ways,布布扣,bubuko.com

LeetCode Decode Ways

原文:http://www.cnblogs.com/lailailai/p/3599468.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!