タイトル
AZがでエンコードされた文字を含むメッセージ:
'A' -> 1
'B' -> 2
...
'Z' -> 26
空でない文字列が数字だけを含む所定の復号方法の合計数を計算します。
例1:
入力: "12"
出力:2
説明:それは"AB"(1 2)または"L"(12)のように復号することができます。
例2:
入力: "226"
出力:3
説明:それは"BZ"(2 26)のように復号することができる "VF"(22 6)、 または"BBF"(2 2 6) 。
分析
現在のビットが0であり、そして結合(自ないデコード0)前にデコードされなければならない場合には、[N-2]の方法(プレビットDP I(I)の方法を想定)があり、DP
現在位置が1-9の場合は、2つのケースがあります
1は、独立して、[N-1]の方法DPと、今回デコード
この時点で[N-2]の方法がDP、前にデコードと一緒に2、。(このアプローチは、1~26の間の結合の前と現在位置を満たすために復号化を必要とします)
DPのため、状態遷移式[I] = DP [I-1] + DP [I-2](特定の条件が満たされたとき、満足DPなかった[i]のDPを= [I-1])
コードは以下の通りであります:
public int numDecodings(String s) {
int len = s.length();
if(s.charAt(0) == '0') return 0;
if(len == 0 || len == 1) return len;
for(int i = 1;i < len;i++){
//只要有00连在一起就是0,比如100
if(s.charAt(i-1) == '0' && s.charAt(i) == '0'){
return 0;
}
//0前面接着比2大的数就是0,比如50
if(s.charAt(i) == '0' && s.charAt(i-1) > '2'){
return 0;
}
}
int[] dp = new int[len];
dp[0] = 1;
int PreTwoNum = (s.charAt(0) - 48) * 10 + (s.charAt(1) - 48);
//第二位不为0且前两位组合起来处于10-26之间,并且不为20为两种方式,否则为1种方式
dp[1] = PreTwoNum > 10 && PreTwoNum <= 26 && PreTwoNum != 20 ? 2 : 1;
for(int i = 2;i < len;i++){
if(s.charAt(i) == '0'){
dp[i] = dp[i - 2];
}else{
int TwoNum = (s.charAt(i-1) - 48) * 10 + (s.charAt(i) - 48);
if(TwoNum <= 26 && TwoNum >= 11){
dp[i] = dp[i - 1]+dp[i - 2];
}else{
dp[i] = dp[i - 1];
}
}
}
return dp[len - 1];