leetcode-91. 解码方法

91. 解码方法

题目

一条包含字母 A-Z 的消息通过以下映射进行了 编码 :

‘A’ -> “1”
‘B’ -> “2”

‘Z’ -> “26”
要 解码 已编码的消息,所有数字必须基于上述映射的方法,反向映射回字母(可能有多种方法)。例如,“11106” 可以映射为:

“AAJF” ,将消息分组为 (1 1 10 6)
“KJF” ,将消息分组为 (11 10 6)
注意,消息不能分组为 (1 11 06) ,因为 “06” 不能映射为 “F” ,这是由于 “6” 和 “06” 在映射中并不等价。

给你一个只含数字的 非空 字符串 s ,请计算并返回 解码 方法的 总数 。

题目数据保证答案肯定是一个 32 位 的整数。

分析

简单的动态分析,dp[i]=dp[i-1]+dp[i-2],主要难点在于边界条件。

当当前char为0时,如果是字符串首尾||前一个char为0或者前一个char+0大于26,则不符合条件,返回0;否则dp[i] = dp[i-2],因为当前char必须与前一个结合。

当当前char不为0时,last_char+cur_char在[1,26]内,dp[i] = dp[i-1]+dp[i-2],否则dp[i] = dp[i-1];

上述过程只用到dp[i-2],dp[i-1],dp[i],所以可以优化。用三个变量存储

注:官方代码简洁一点

代码

public int numDecodings(String s) {
    if(Integer.parseInt(s.substring(0,1))==0) return 0;
    int[] dp = new int[s.length()+1];
    dp[0] = 1;
    dp[1] = 1;
    for(int i=2;i<dp.length;i++){
        if(Integer.parseInt(s.substring(i-1,i))==0){
            if(Integer.parseInt(s.substring(i-2,i))==0 || Integer.parseInt(s.substring(i-2,i))>26){
                return 0;
            }
            else {
                dp[i] = dp[i-2];
            }
        }
        else if(Integer.parseInt(s.substring(i-2,i-1))!=0 && Integer.parseInt(s.substring(i-2,i))>10 && Integer.parseInt(s.substring(i-2,i))<=26){
            dp[i] = dp[i-1]+dp[i-2];
        }
        else{
            dp[i] = dp[i-1];
        }
    }
    return dp[s.length()];
}

// 优化后
public int numDecodings(String s) {
    if(Integer.parseInt(s.substring(0,1))==0) return 0;
    int left = 1;
    int right = 1;
    int temp;
    for(int i=1;i<s.length();i++){
        if(Integer.parseInt(s.substring(i,i+1))==0){
            if(Integer.parseInt(s.substring(i-1,i+1))==0 || Integer.parseInt(s.substring(i-1,i+1))>26){
                return 0;
            }
            else {
                temp = right;
                right = left;
                left = temp;
            }
        }
        else if(Integer.parseInt(s.substring(i-1,i))!=0 && Integer.parseInt(s.substring(i-1,i+1))>10 && Integer.parseInt(s.substring(i-1,i+1))<=26){
            temp = left + right;
            left = right;
            right = temp;
        }
        else{
            left = right;
        }
    }
    return right;
}

结果

时间超过35.39%

内存超过5.03%

你可能感兴趣的:(leetcode,leetcode,动态规划,算法)