leetcode 639. Decode Ways II

来源:互联网 发布:吉林省网络教育jlsedu 编辑:程序博客网 时间:2024/06/04 00:44
  1. 原理
    动态规划,设dp[i]为[0,i]之间的数字与字母的合法匹配的总数。先计算第i个数字单独匹配一个字母的情况下的数量(设为xi),再计算第i-1和i个数字组成一个两位数匹配一个字母的情况下的数量(设为yi),则dp[i]=xidp[i1]+yidp[i2]
  2. 合法匹配的数量列表
    1)1位数

    数字 匹配数目 1-9 1 * 9

    2) 2位数

    十位数 个位数 匹配数目 1 0-9 1 2 0-6 1 * 0-6 2 * 7-9 1 1 * 9 2 * 6 * * 15
  3. 算法源码

#define MOD_NUMBER 1000000007#define SYMBOL_CASE(symbol) case symbol:#define ZERO_CASE \SYMBOL_CASE('0')#define ONE_CASE \SYMBOL_CASE('1')#define TWO_CASE \SYMBOL_CASE('2')#define ONE_SIX_CASE \ONE_CASE \TWO_CASE \SYMBOL_CASE('3') \SYMBOL_CASE('4') \SYMBOL_CASE('5') \SYMBOL_CASE('6')#define SEVEN_NINE_CASE \SYMBOL_CASE('7') \SYMBOL_CASE('8') \SYMBOL_CASE('9')#define ONE_NINE_CASE \ONE_SIX_CASE \SEVEN_NINE_CASE#define ZERO_SIX_CASE \ZERO_CASE \ONE_SIX_CASE#define ZERO_NINE_CASE \ZERO_CASE \ONE_NINE_CASE#define ASTERISK_CASE \SYMBOL_CASE('*')#define PROCESS_CASE(condition, result) \condition \    number = result; \break;int num_ways_one_char(char c){    int number = 0;    switch (c)    {        PROCESS_CASE(ONE_NINE_CASE, 1)        PROCESS_CASE(ASTERISK_CASE, 9)    default:        break;    }    return number;}int num_ways_two_char(char c1, char c2){    int number = 0;    switch (c1)    {        ONE_CASE            switch (c2)            {                PROCESS_CASE(ZERO_NINE_CASE, 1)                PROCESS_CASE(ASTERISK_CASE, 9)            default:                break;            }            break;        TWO_CASE            switch (c2)            {                PROCESS_CASE(ZERO_SIX_CASE, 1)                PROCESS_CASE(ASTERISK_CASE, 6)            default:                break;            }            break;        ASTERISK_CASE            switch (c2)            {                PROCESS_CASE(ZERO_SIX_CASE, 2)                PROCESS_CASE(SEVEN_NINE_CASE, 1)                PROCESS_CASE(ASTERISK_CASE, 15)            default:                break;            }            break;    default:        break;    }    return number;}int numDecodings(char* s) {    int curr_c;    int pre_c;    long long curr_res;    long long pre_res = 1;    long long next_res;    curr_c = *(s++);    curr_res = num_ways_one_char(curr_c);    pre_c = curr_c;    curr_c = *(s++);    if(!curr_c || !curr_res)return curr_res;    do     {        next_res = ((curr_res * num_ways_one_char(curr_c) % MOD_NUMBER) +            (pre_res * num_ways_two_char(pre_c, curr_c) % MOD_NUMBER)) % MOD_NUMBER;        pre_res = curr_res;        curr_res = next_res;        if (!curr_res) return 0;        pre_c = curr_c;        curr_c = *(s++);    } while (curr_c);    return curr_res;}
原创粉丝点击