十进制转换为二十六进制的方式 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).

解决:

① 给定一个已经编码过的字符串,判断有几种解码方式。例如:

“12” ---> “AB”,“L”。

“125” ---> “ABE”,“AY”,“LE” 

由编码规则可知,编码范围为1 ~ 26,可以知道,一个大写字母可以编码至多两个数字,所以,可以发现,解决方法与climb stairs类似,使用动态规划,假设数组dp[i]表示从头到字符串的第i位,一共有多少种解码方法的话,如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们是在第i-2位的解码方法上继续解码(dp[i] += dp[i-2])。如果字符串的第i-1位和第i位不能组成有效二位数字,而且第i位不是0的话,说明我们是在第i-1位的解码方法上继续解码(dp[i] += dp[i - 1])。所以,如果两个条件都符合,则dp[i]=dp[i -1]+dp[i + 2],否则dp[i] = dp[i - 1]。

class Solution {//5ms
    public int numDecodings(String s) {
        if(s.length() ==0) return s.length();
        int[] dp = new int[s.length() + 1];
        dp[0] = 1;//初始化第一种解码方式
        dp[1] = s.charAt(0) == '0' ? 0 : 1;//如果第一位是0,则无法解码
        for(int i = 2;i <= s.length();i ++){
            // 如果字符串的第i-2位和第i-1位能组成一个10到26的数字,说明我们可以在第i-2位的解码方法上继续解码,有两位数字
            if(Integer.parseInt(s.substring(i - 2,i)) <= 26 && Integer.parseInt(s.substring(i - 2,i)) >= 10){
                dp[i] += dp[i - 2];
            }
            // 如果字符串的第i-2位和第i-1位不能组成有效二位数字,在第i-1位的解码方法上继续解码,只有一位数字
            if(Integer.parseInt(s.substring(i-1, i)) != 0){
                dp[i] += dp[i - 1];
            }
        }
        return dp[s.length()];
    }
}

另一种解法:

class Solution { //2ms
    public int numDecodings(String s) {
        if(s == null || s.length() == 0 || (s.length() > 1 && s.charAt(0) == '0')) return 0;
        int[] dp = new int[s.length() + 1];
        dp[0] = 1;//初始化第一种解码方式
        for (int i = 1;i < dp.length ;i ++ ) {
            dp[i] = (s.charAt(i - 1) == '0') ? 0 : dp[i - 1];//在第i-1位的解码方法上继续解码
            if(i > 1 && (s.charAt(i - 2) == '1' || (s.charAt(i - 2) == '2') && s.charAt(i - 1) <= '6')){//如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们可以在第i-2位的解码方法上继续解码
                dp[i] += dp[i - 2];
            }
        }
        return dp[s.length()];
    }
}

② 在discuss中看到的,使用两个变量,分别记录一位数和两位数的情况。

class Solution {//1ms
    public int numDecodings(String s){
        if (s.length() == 0) return 0;
        int preFir = 1;
        int preSec = 1;
        char[] schar = s.toCharArray();
        for (int i = 0;i < schar.length;i ++){
            int way = 0;
            int val1 = schar[i] - '0';
            if (val1 >= 1 && val1 <= 9){//1~9之间
                way += preFir;
            }
            if (i >= 1){//10~26之间
                int val2 = (schar[i - 1] - '0') * 10 + val1;
                if (val2 >= 10 && val2 <= 26){
                    way += preSec;
                }
            }
            preSec = preFir;
            preFir = way;
        }
        return preFir;
    }
}

转载于:https://my.oschina.net/liyurong/blog/1538764

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值