A message containing letters from was A-Z
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: "Output:2explanation:it" could be decoded as "AB" (1 2) or "L" (12).
Example 2:
Input: "226" output:3explanation:it could be decoded as "BZ" (2), "VF" (6), or "BBF" (2 2 6).
This question thought for a long time, think really is more difficult to think, a lot of case over and over again test before passing. Try to summarize the idea.
First of all, if we analyze the middle, more general situation.
Now on the basis of the existing string, a new character will begin to divide the situation. If it comes to ' 0 ', there is only one composition, which is encoded with the previous number, and the preceding number must be ' 1 ' or ' 2 ', otherwise it is an invalid encoding. So if it comes to ' 0 ', it's equivalent to either a combination with the previous number, or it's invalid. If you use the idea of dynamic planning, write the Pseudo-code first:
if (s[i] = = ' 0 ') { if (s[i-1] = = ' 1 ' | | ' 2 ') dp[i] = dp[i-2]; else return 0;}
Why here is dp[i] = dp[i-2]? Because ' 0 ' can only be used as a combination of the preceding characters, the preceding character appears as if it does not appear, as it will wait for the next ' 0 ' to be combined with it, so there are as many coding types as dp[i-2].
Next see if Come is ' 1 ' ~ ' 9 ', not only oneself want to subdivide the situation again, also want to consider the situation of the front one again. If the previous one is ' 1 ', or the previous one is ' 2 ' and this bit is ' 1 ' ~ ' 6 ', then a new encoding can be generated, because it can be either independent of a single letter, and can be combined with the preceding number to form a letter. As a stand-alone situation is equivalent to taking dp[i-1], because the addition of a separate character does not increase any possibility, so it remains the same as the former state, as the combination exists, but also to think of another. Because if the combination exists, the previous one is actually the same as the following one as a combination of existence rather than independent existence, that is, when dp[i-1] that character, pretending that it did not come, because it is to wait and the following characters, so the encoding type and dp[i-2] is the same as many. So the last dp[i] = dp[i-1] + dp[i-2].
If the previous character is not ' 1 ' or ' 2 ', then the new character bit can only exist as a standalone and cannot be combined. So there is no new coding possible, ie dp[i] = dp[i-1].
The pseudo code is summarized as follows:
if (s[i-1] = = ' 1 ' | | (S[i-1] = = ' 2 ' && ' 1 ' <= s[i] <= ' 6 ')) Dp[i] = dp[i-1] + dp[i-2];else dp[i] = dp[i-1];
So all the situation is analyzed. Now look at what needs to be done to solve the general situation, it is clear from the above that you need to know the first two bits of each character, that is, dp[0] and dp[1. Dp[0] very simple, if not ' 0 ' that is 1, is ' 0 ' directly return 0, the first bit is ' 0 ' cannot decode. DP[1] is not complicated, in fact, as in the general case, if the second bit is ' 0 ', dp[1] is 1 or return 0, depending on whether the first bit is ' 1 ' or ' 2 ', if the first bit is ' 1 ', or the first bit is ' 2 ' and the second is ' 1 ' ~ ' 6 ', that dp[1 ] is 2, because it can be combined or independent of existence. All other cases are 1, because they can only exist independently, without increasing the likelihood of decoding.
After writing the idea found that the problem is finished, the idea of implementation is the code. There should be a lot of places to optimize, or thoughts, or code, to stay for the time to review the optimization bar. Now this way of thinking is particularly clear, it is easy to understand, let's do it!
Java
classSolution { Public intnumdecodings (String s) {if(s = = "")return0; Char[] digit =S.tochararray (); int[] DP =New int[Digit.length]; //get dp[0]Dp[0] = digit[0] = = ' 0 '? 0:1; if(dp[0] = = 0 | | digit.length = = 1)returnDp[0]; //get dp[1]DP[1] = 1; if(digit[1] = = ' 0 ') { if(Digit[0] >= ' 3 ') return0; } Else if(digit[0] = = ' 1 ' | | (digit[0] = = ' 2 ' && ' 1 ' <= digit[1] && digit[1] <= ' 6 ')) dp[1] = 2; //get Dp[i] for(inti = 2; i < digit.length; i++) { if(Digit[i] = = ' 0 ') { if(Digit[i-1] = = ' 1 ' | | digit[i-1] = = ' 2 ') Dp[i]= Dp[i-2]; Else return0; } Else if(Digit[i-1] = = ' 1 ' | | (Digit[i-1] = = ' 2 ' && ' 1 ' <= digit[i] && digit[i] <= ' 6 ')) Dp[i]= Dp[i-1] + dp[i-2]; ElseDp[i] = dp[i-1]; } returnDp[digit.length-1]; }}
(Java) Leetcode 91. Decode ways--Decoding method