Leetcode91. 解码方法(C语言)

Leetcode91. 解码方法(C语言)

算法-动态规划(分割整数):算法与数据结构参考

题目:
一条包含字母 A-Z 的消息通过以下方式进行了编码:
‘A’ -> 1;‘B’ -> 2;…;‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数。例:
输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)。

思路:
动态规划。由于不确定是一个还是两个字符组合,故分情况分析。
假设第i个字符解码方式为dp[i],两两组合判断:
第i-1位和第i位值,val = 10 * (s[i-1] - ‘0’) + (s[i] - ‘0’).考虑如下几种情形:
(1)val = 0,第i-1位和第i位为’00’。‘0’开头无法对应,故dp[i] = 0, 结束;
(2)0 < val < 10,第i-1位为’0’,第i位为’1’-‘9’。此时dp[i] = dp[i-1];
(3)val = 10 或val = 20,第i-1位为’1’或’2’,第i位为’0’。dp[i] = dp[i-2];
(4)10 < val <= 26 && val != 20,此时dp[i] = dp[i-1] + dp[i-2];
(5)val > 26 并 s[i] = ‘0’,此时无法编码,dp[i] = 0,并返回dp[i];
(6)val > 26 并 s[i] != ‘0’,此时dp[i] = dp[i-1]。
参考题解

代码:

int numDecodings(char * s){
    int len;
    for(len=0;s[len];len++);
    
    if(len==0 || (len==1 && s[0]-'0'==0))  return 0;
    else if(len==1 && s[0]-'0'>0)    return 1; 

    int pre1=1,pre2,tmp;
    int val=(s[0]-'0')*10+(s[1]-'0');
    if(val==0 || (0<val && val<10))  return 0;
    else if(val==10 || val==20)  pre2=1;
    else if(10<val && val<=26)    pre2=2;
    else if(val>26){
        if(s[1]!='0') pre2=1;
        else return 0;
    }   //初始化

    for(int i=2;i<len;i++){
        val=(s[i-1]-'0')*10+(s[i]-'0');
        if(val==0)  return 0;
        else if(0<val && val<10) pre1=pre2;
        else if(val==10 || val==20){  
            tmp=pre1;
            pre1=pre2;
            pre2=tmp;
        }   //两个数看成整体
        else if(10<val && val<=26){
            tmp=pre1+pre2;
            pre1=pre2;
            pre2=tmp;
        }
        else if(val>26){
            if(s[i]!='0') pre1=pre2;
            else return 0;
        }   
    }
    return pre2;
}
//if...else if...不能为了偷懒除去else,会报错(各个if相当与并列,顺序不定)

你可能感兴趣的:(数据结构&算法)