A message containing letters from A-Z
is being encoded to numbers using the following mapping:
'A' -> 1 'B' -> 2 ... 'Z' -> 26
Given a non-empty string containing only digits, determine the total number of ways to decode it.
Example 1:
Input: "12" Output: 2 Explanation: It could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226" Output: 3 Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
解法:
递归,复杂度太大,会超时。
class Solution {
public int numDecodings(String s) {
return findAns(s,0,1)+findAns(s,0,2);
}
public int findAns(String s, int len, int step){
if(len > s.length() || len+step > s.length()){ //判断越界问题
return 0;
}else{
//取相应的位数
String str = s.substring(len,len+step);
int num = Integer.valueOf(str);
if(str.startsWith("0"))return 0; //1000,01,001等情况
if(num<=26 && num>0){
if(len+step == s.length()){ //立即返回
return 1;
}
return findAns(s,len+step,1)+findAns(s,len+step,2);
}else{
return 0;
}
}
}
}
解法二:
动态规划,为了处理方便,取多一位,省去各种判断。
把当前位取出,成为one。把当前位和前一位取出,成为two。
当10<=two<=26的时候,说明可以从前两位就开始计数。dp[n] += dp[n-2]。
当one!=0的时候,说明还能自己自立门户,所以再要加上dp[n-1],即dp[n]+=dp[n-1]。
class Solution {
public int numDecodings(String s) {
if(s.length() == 0) return s.length();
int[] dp = new int[s.length() + 1];
Arrays.fill(dp,0);
dp[0] = 1;
if(s2int(s,0,1) !=0)dp[1]=1;
for(int i=1;i<s.length();i++){
int one = s2int(s,i,i+1);
int two = s2int(s,i-1,i+1);
if(two>=10 && two<=26){
dp[i+1]+=dp[i-1];
}
if(one!=0){
dp[i+1]+=dp[i];
}
}
return dp[s.length()];
}
public int s2int(String s,int begin,int end){
return Integer.valueOf(s.substring(begin,end));
}
}