Dynamic programming cleverly solves LeetCode "decoding method" problem

Question source: LeetCode 91. Decoding method

1. Title

A message containing the letters AZ is encoded in the following way:

'A' -> 1
'B' -> 2
...
'Z' -> 26

Given a non-empty string containing only numbers, please count the total number of decoding methods.

Example 1:

输入: "12"
输出: 2
解释: 它可以解码为 "AB"1 2)或者 "L"12)。

Example 2:

输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6)

2. Problem solving ideas

2.1 Why do you think of dynamic programming?

The first step in solving the problem is to look at the requirements of the problem, that is, to calculate the total number of decoding methods . Combined with the example, we can see that sthere are only two cases when a character in the string is encoded :

  • Alone as a code
  • It forms a code together with the previous character (the code composed of the current character and the following character can be regarded as the result of the combination of the latter character and the current character, and can be regarded as the second case of the latter character)

According to the above connection, we can find that the problem has an optimality principle , and the state of the latter stage depends only on the previous state, so dynamic programming can be considered.

2.2 Find the state transition equation

Assume dp [n − 1] dp[n-1]dp[n1 ] represents thes[0...n-1]total number of encoding methods of thesubstring,dp [n − 2] dp[n-2]dp[n2 ] Represents thes[0...n-2]total number of encoding methods for thesubstring, the current character iss[n],s[0...n]how to calculate the total number of encoding methodsforthe current substring? It’s actually very simple:
dp [n] = dp [n − 1] + addnums dp[n] = dp[n-1] + addnumsdp[n]=dp[n1]+addnums
其中 a d d n u m s addnums a d d n u m s represents the number ofnewly added coding methods, which can be 0, which means that no new coding methods are added. Where does the number of new encoding methods come from? According to the two situations mentioned earlier:

  • Case 1 : It does not need to be taken into consideration, because the current character encoding method has been considered when the previous character is individually encoded
  • Case 2 : It needs to be considered, because the s[n-1]s[n-1]combined coding situation cannot be included in the previous method. At this time, the number of new methods is actually dp [n − 2] dp[n-2]dp[n2 ] Total number of encoding methods

In summary, the state transition equation can be drawn as follows:
dp [n] = {dp [n − 1] + dp [n − 2] INT (s [n − 1] s [n]) ∈ [1, 26] 0 others dp[n]=\begin{cases} dp[n-1] + dp[n-2] & INT(s[n-1]s[n])\in[1,26] \\ 0 & others \ \ \end{cases}dp[n]={ dp[n1]+dp[n2]0INT(s[n1]s[n])[1,26]others
Where INT (s [n − 1, n]) INT(s[n-1,n])INT(s[n1,n ] ) means toconverts[n-1]sn[n]the substring formed into an integer.

2.3 State initialization

In order to facilitate the recursion from the first character of the original string, you can consider adding a character before the original string '3', ie s = '3' + s. Then initialize the array dpwith the initial value of 0 and the length of the new string , and initialize it dp[0]=1.

2.4 Consider the special case with 0

There is also a special case that needs to be considered in this question, that is, the input string scontains 0. When it appears s[i]=0, the only situation that s[i-1]s[i]can be encoded at this time can only be composed in the range of [0, 26] [0, 26][0,2 6 ] , otherwise it cannot be coded. To facilitate understanding, a few examples are given below:

#可以进行编码的例子
s='11012321'
#无法进行编码的例子
s='0123'
s='130243'
s='1003458'

Therefore, when 0 appears, it is necessary to determine whether the substring composed of the current character s[i]and the previous character s[i-1]can form a valid encoding. If it cannot directly return 0, the encoding cannot be performed, otherwise dp [i] = dp [i − 2] dp[i]=dp[i-2]dp[i]=dp[i2]

3. Algorithm demonstration video

Here is s=12021an example, the following is a dynamic demonstration video of the algorithm:
alg_video

Four. Sample program

Based on the above points, the sample code is given below:

from typing import List

class Solution:
    def numDecodings(self, s: str) -> int:
        condition = lambda x:(int(x) <= 26 and int(x) > 0 and x[0]!='0')
        s = '3' + s
        n = len(s)
        dp = [0] * n
        dp[0] = 1 
        for i in range(1,n):
            if s[i] == '0':
                if condition(s[i-1:i+1]):#当前字符为0但与其前一个字符能够组成合法编码
                    dp[i] = dp[i - 2]
                else:
                    return 0
            else:
                dp[i] = dp[i - 1] + ( dp[i - 2] if condition(s[i-1:i+1]) else 0)
        return dp[-1]

The above is the whole content of this article. If you think it is good, please like or pay attention to the blogger. Follow-up will continue to update various algorithmic solutions. If you find any problems, please criticize and correct! ! !

Guess you like

Origin blog.csdn.net/qq_42103091/article/details/108689862