[Dynamic programming to fight monsters and upgrade] - Decoding method


1. Dynamic programming leveling strategy

  • 1. Status representation (determine the meaning of the dp array)

  • 2. State transition equation (determined recursive formula)

  • 3. Initialization

  • 4. Traversal order

  • 5. Return value

2. Decoding method

decoding method

insert image description here

Idea: dynamic programming

  • 1. Determine the state representation (the meaning of dp[i])
    dp[i]: There are dp[i] kinds of decoding methods ending at the i-th position.

  • 2. Determine the state transition equation (dp[i] is equal to what)
    let's analyze:
    insert image description here

Indicated by the status, the decoding methods can be divided into:

      1. s[i] is decoded individually
      1. s[i] and s[i-1] are decoded together

If it is the first case, there are two cases for s[i]:
s[i] decodes successfully and s[i] fails to decode.

(1)

If the decoding of s[i] fails, no matter whether the previous decoding of s[i] is successful or not, it will be completely cleared. So when s[i] fails to decode, there are 0 ways.

(2)

If s[i] is successfully decoded, then dp[i] = dp[i-1]
because if s[i] is successfully decoded, it means that all characters before it must be decoded successfully, and the number of methods is dp[i-1] number of methods. This is similar to the problem of climbing stairs. There are only two situations to climb to the i-th floor of the stairs, one step up the i-1st floor, or two steps up the i-2th floor. The method numbers are all dp[i-1] or dp[i-2].
Then the prerequisite for successful decoding is: 9 >= a >=1

The above is the case where s[i] is decoded alone.

The following is the case where s[i] and s[i-1] are decoded together.

(1) If s[i] and s[i-1] fail to decode together, then even if s[i-1] was successfully decoded before, the total number of decoding methods is 0.

(2) If s[i] and s[i-1] are successfully decoded together, then dp[i] = dp[i-2].
Then the prerequisite for successful decoding is:
10<= b*10 + a <= 26, b is a number in the tens digit, so it needs to be multiplied by 10. Note that
this is greater than or equal to 10, not greater than or equal to 1.
Because if it is greater than or equal to 1, the following situation will occur:
insert image description here
Pay attention to the requirements of the title, the string preceded by 0 cannot be decoded alone.

So the state transition equation is:

dp[i] = dp[i-1] + dp[i-2]

There is one more point to note:

Why is s[i] and s[i-1] decoded together, not s[i] and s[i+1]?
We need to note that the meaning of dp[i] is: the number of decoding methods ending at position i is dp[i]. When we calculate the position of s[i], the subsequent position has not been considered, so it is s [i] decodes with s[i-1] instead of s[i] with s[i+1].

  • 3. How to initialize
    From the state transition equation: dp[i] = dp[i-1] + dp[i-2]. We should initialize dp[0] and dp[1]. When s[0] is decoded alone, there
    is There are two cases of success and failure, so dp[0] = 0/1;
    the code is as follows:
dp[0] = s[0] != '0'

When s[0] and s[1] are jointly decoded, the following situations occur:
(1) Decoding fails, that is, s[0] is leading 0. dp[1] = 0
(2) s[0]!='\0', it will be successfully decoded once, dp[1] +=1
(3) 10<= b*10 + a <= 26, indicating At this time, it can be decoded together, dp[1] +=1, at this time dp[1] = 2;

code show as below:

//s[1] 和 s[0]一起解码的情况
if(s[0] !='0' && s[1]!='0')
     dp[1] +=1;//只要s[0]不是0,就可以解码一次
     
int t = (s[0] -'0')*10 + s[1] - '0' ; 

if(t >= 10 && t <= 26)//同时可以解码
     dp[1] +=1;
  • 4. Traversal order
    According to the state transition equation, the traversal order is from left to right, and the traversal should start from position i = 2.

  • 5. Return value
    Just return dp[ n-1 ].

The specific code is as follows:

class Solution {
    
    
public:
    int numDecodings(string s) 
    {
    
    
        //1.确定dp数组的含义
        //2.确定递推公式
        //3.如何初始化
        //初始化dp[0] = 0/1 和dp[1] = 0/1/2
        //4.如何进行遍历
        //5.返回值
        
        //字符串解码有两种情况1:s[i]单独解码,成功的话,dp[i] = dp[i-1];
        //2.s[i] 和 s[i-1]一起解码,如果((s[i-1]-'0')*10 + s[i]-'0') >=10 && ..<=26,解码成功,dp[i] = dp[i-2];

        //所以dp[i] = dp[i-1] + dp[i-2];
        int n = s.size();
        vector<int> dp(n);

        dp[0] = s[0] !='0';//单独解码的情况
        
        //s[1] 和 s[0]一起解码的情况
        if(s[0] !='0' && s[1]!='0')
            dp[1] +=1;//只要s[0]不是0,就可以解码一次

        int t = (s[0] -'0')*10 + s[1] - '0' ; 
        if(t >= 10 && t <= 26)//同时可以解码
            dp[1] +=1;            
            
        for(int i = 2;i<n;i++)
        {
    
    
            if(s[i] != '0')//单独解码,成功
                dp[i] += dp[i-1];
            int t = (s[i-1] -'0')*10 + s[i] - '0';
            if(t >= 10 && t <= 26)//第二种情况,解码成功
                dp[i] += dp[i-2];
        }
        return dp[n-1];
    }
};

时间复杂度O(n),空间复杂度O(n)

Summarize

Today I wrote a question about the decoding method, which is more difficult, but it also left an impression.

Guess you like

Origin blog.csdn.net/2301_76496134/article/details/131493708