您的位置:首页 > 其它

91. Decode Ways

2016-07-05 11:46 344 查看
题目:

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).

The number of ways decoding 
"12"
 is 2.

题意:

给你一串数字,解码成英文字母。

思路一:

动态规划(DP),定义S数组,S[i]表示:字符串S[0...i-1]可以有S[i]中解码方式。一般情况下:

1、如果S[i] == '0',如果S[i-1]存在且为'1'或者'2',F[i] = F[i-1],否则无解; 
2、如果S[i] != '0' 

        如果S[i-1]=='1',F[i] = F[i-1] + F[i-2](例如"xxxxxx11",可以是"xxxxxx11",也可以是"xxxxxx1" + "1“); 

        如果S[i-1]=='2',当S[i] <= '6'时,F[i] = F[i-1] + F[i-2] (最大的Z为"26","27""28""29"不存在),当S[i] > '6'时,F[i] = F[i-1] (例如"xxxxxx28",只能是"xxxxxx2" + "8")。 

代码:2ms

public class Solution {
    public int numDecodings(String s) {
        if (s == null || s.length() == 0)
            return 0;
        int[] S = new int[s.length()];
        
        for (int i=0; i<s.length(); i++) {
            if (s.charAt(i) == '0') {
                if (i == 0 || s.charAt(i-1) == '0' || s.charAt(i-1)>'2')  //表示超出编码范围
                    return 0;
                else
                    S[i] = i > 1 ? S[i-2] : 1;
            } else {
                if (i > 0 && (s.charAt(i-1)=='1' || s.charAt(i-1)=='2' && s.charAt(i)<'7')) {
                    S[i] = S[i-1] + (i>1 ? S[i-2] : 1);
                } else {
                    S[i] = i > 0 ? S[i-1] : 1;
                }
            }
        }
        return S[s.length()-1];
    }
}

思路二:转载地址:https://segmentfault.com/a/1190000003813921

解码是有规律的,所以我们可以尝试动态规划。假设数组dp[i]表示从头到字符串的第i位,一共有多少种解码方法的话,那么如果字符串的第i-1位和第i位能组成一个10到26的数字,说明我们是在第i-2位的解码方法上继续解码。如果字符串的第i-1位和第i位不能组成有效二位数字,而且第i位不是0的话,说明我们是在第i-1位的解码方法上继续解码。所以,如果两个条件都符合,则dp[i]=dp[i-1]+dp[i-2],否则dp[i]=dp[i-1]。注意:如果出现无法被两位数接纳的0,则无法解码,我们可以在一开始就判断,并将其初始化为0,这样后面的相加永远都是加0。

代码:6ms

public class Solution {
    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-1位和第i位能组成一个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-1位和第i位不能组成有效二位数字,在第i-1位的解码方法上继续解码
            if (Integer.parseInt(s.substring(i-1, i)) != 0) {
                dp[i] += dp[i-1];
            }
        }
        return dp[s.length()];
    }
}
另一种写法:6ms
public class Solution {
    public int numDecodings(String s) {
        int n = s.length();
        if (n == 0) return 0;
        
        int[] memo = new int[n+1];
        memo
= 1;
        memo[n-1] = s.charAt(n-1) != '0' ? 1 : 0;
        
        for (int i=n-2; i>=0; i--) {
            if (s.charAt(i) == '0')
                continue;
            else
                memo[i] = (Integer.parseInt(s.substring(i, i+2)) <= 26) ? memo[i+1] + memo[i+2] : memo[i+1];
        }
        return memo[0];
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: