程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> [C++]LeetCode: 55 Decode Ways

[C++]LeetCode: 55 Decode Ways

編輯:關於C++
題目:

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.

思路:

設置動態數組dp[i], dp[i]表示字符串 s[0,1,2,....,i-1]的decode way的個數。

注意,如果序列中有不能匹配的0,那麼解碼的方法是0,比如序列012,,100(第二個0可以和1組成10,但是第三個0不能匹配)。

分成兩種情況討論,考慮末尾一個數字以及考慮末尾兩個數字。動態規劃方程:

初始條件:dp[0] = 1(根據判斷兩個數字dp[2] += dp[0] 確定), dp[1] = (s[0] == '0') ? 0 :1

遞推公式:1.考慮s[0,1,2,...,i-1]末尾一個數字當做一個字母考慮,dp[i]【1】 = s[i-1] == 0 ? 0 : dp[i-1]

2.考慮s[0,1,2,...,i-1]末尾兩個數字當做一個字母考慮,dp[i]【2】 = isValid(s[i-2, i-1]) == true ? dp[i-2] :0

3. dp[i] = dp[i]【1】+ dp[i]【2】

Attention:

1. 初始條件dp[0]的設置,需要根據代碼具體含義確定,需符合實際意義(dp[2] += dp[0],此處dp[0]表示s[0,1]代表一個字母,所以取1) 。

2. 如果序列中有不能匹配的0,那麼解碼的方法是0。 這點容易忽視,一定要注意。如果某字符為0,則不能解碼,只考慮它是否可以前一個字符組成合法字符。

3. 加入合法字符判斷的helper程序(isValid()),可以使代碼含義更加清晰。但是也可以采取直接判斷。代碼如下:

for(int i = 2; i <= len; i++)
        {
            if(s[i-1] != '0')
                dp[i] = dp[i-1];
            else dp[i] = 0;
            if(s[i-2] == '1' || (s[i-2] == '2' && s[i-1] <= '6'))
                dp[i] += dp[i-2];
        }

4. 動態方程的遞推方式,以及dp[i]的含義確定,需要准確和考慮全面。

復雜度:O(N)

AC Code:

class Solution {
public:
    int numDecodings(string s) {
        int len = s.length();
        if(len == 0) return 0;
        
        //dp[i]表示s[0,1,...,i-1]的解碼方法數目
        int dp[len+1];
        
        //初始化dp[0],dp[1]
        dp[0] = 1;
        if(s[0] != '0')
        {
            dp[1] = 1;
        }
        else
        {
            dp[1] = 0;
        }
        
        for(int i = 2; i <= len; i++)
        {
            //如果末尾數字為無效0,則dp為0
            if(isValid(s.substr(i-1, 1)))
            {
                dp[i] = dp[i-1];
            }
            else
            {
                dp[i] = 0;
            }
            
            if(isValid(s.substr(i-2, 2)))
            {
                dp[i] += dp[i-2];
            }
        }
        
        return dp[len];
    }

public:
    bool isValid(string str)
    {
        //如果str中含無效的0,如“02”,解碼失敗
        if(str[0] == '0')
            return false;
        int num = std::stoi(str);
        if(num >= 1 && num <= 26)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};



  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved