題目:
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.
題意及分析:本題給出A-Z字符對應的數字,給出一個數字組成的字符串,要求求出可能A-Z組成的編碼。這道題還是動態規划的題目,對於字符串中第i(i>2)個字符,因為編碼最大的數字是26,所以到該點可能的編碼方式和前一個字符也相關,如果當前字符和前一個字符組成的數字d=s.charAt(i-1)*10+s.charAt(i),
(1)當0<d<=26,如果d%10!=0,有兩種方式到達第i個字符(從第i-1字符加一個字符達到、從第i-2個字符加一個字符達到),即f(s.charAt(i))=f(s.charAt(i-1))+f(s.charAt(i-2));如果i%10=0,則只有一種方式達到f(s.charAt(i))=f(s.charAt(i-2))
(2)當d>26,如果d%10!=0,則一種方法到達i點(即從i-1到達i),f(s.charAt(i))=f(s.charAt(i-1));如果d%10=0,則沒有對應的編碼表達d這兩個字符,所以直接return 0
(3)d==0的時候,字符串中出現了兩個連續的0,直接return 0
對於字符串的前兩個數字字符單獨處理,分類同上,然后遍歷字符串就可以得到最終結果。
代碼:
public class Solution {
public int numDecodings(String s) {
int[] A=new int[s.length()]; //記錄當前字符串第i個位置 的decode方法
if(s.length()<=1){
if(s.length()==0)
return 0;
else{
if(s.charAt(0)=='0')
return 0;
else
return 1;
}
}
if(s.length()>=2){
if(s.charAt(0)=='0') //若包含0則返回0
return 0;
}
A[0]=1; //字符串第一位的數肯定只有一種匹配方法
int x=(s.charAt(0)-'0')*10+(s.charAt(1)-'0'); //前兩位數的值
if(x>26&&x%10==0)
return 0;
if(x<=26&&x>0)
if(x!=10&&x!=20)
A[1]=2;
else {
A[1]=1;
}
else if(s.charAt(1)!='0')
A[1]=1;
else {
A[1]=0;
}
for(int i=2;i<s.length();i++){
//記錄當前字符和前一個字符組成的數,若這個數小於等於26,則到當前的方法d(s.charAt(i))=d(s.charAt(i-1))+d(s.charAt(i-2)),否則d(s.charAt(i))=0
int temp=(s.charAt(i-1)-'0')*10+(s.charAt(i)-'0');
if(temp<=26&&temp>0) //在0到26之間且前一個數不為0
if(s.charAt(i-1)!='0'&&s.charAt(i)!='0')
A[i]=A[i-2]+A[i-1];
else A[i]=A[i-2];
else if(temp>26) //中間有大於30的
if(temp%10!=0)
A[i]=A[i-1];
else {
return 0;
}
else //包含兩個連續的0
return 0;
}
return A[s.length()-1];
}
}
方法二:使用動態規划,當前點的編碼方法有兩種情況,要么1、當前數在0-9之間,這樣可以從前一個數到達,2、如果當前數和前一個數能編碼,即在1-26之間,那么從當前數前兩個數可以到達當前數;具體看代碼。
public class Solution { public int numDecodings(String s) { if(s.length() ==0) return 0; int[] count = new int[s.length()+1]; //count[i]記錄從開始到i-1點有count[i]中可能的編碼方式 count[0]=1; if(s.charAt(0)>'0') count[1]=1; for(int i=2;i<=s.length();i++){ if(s.charAt(i-1)>='1') count[i] = count[i-1]; int sum = Integer.parseInt(s.substring(i-2,i)); if(sum <=26 && s.charAt(i-2)!='0' ) count[i] += count[i-2]; } return count[s.length()]; } }
