Leetcode 639. 解碼方法 2【空間優化的動態規劃】

問題描述

一條包含字母 A-Z 的消息通過以下的方式進行了編碼:

‘A’ -> 1
‘B’ -> 2

‘Z’ -> 26
除了上述的條件以外,現在加密字符串可以包含字符 '‘了,字符’'可以被當做1到9當中的任意一個數字。

給定一條包含數字和字符’*'的加密信息,請確定解碼方法的總數。

同時,由於結果值可能會相當的大,所以你應當對109 + 7取模。(翻譯者標註:此處取模主要是爲了防止溢出)

示例 1 :

輸入: “*”
輸出: 9
解釋: 加密的信息可以被解密爲: “A”, “B”, “C”, “D”, “E”, “F”, “G”, “H”, “I”.

解題報告

代碼在 Leetcode 91. 解碼方法 題解區:pris_bupt 的基礎上修改的。

解決這個題目,關鍵在於抓住 當前數字單獨解碼的可能方案數+當前數字和前一個數字合在一起解碼的方案數

所以需要分類討論:

  • 當前數字爲 0 時,要分上一個數字是 1 或者 2 或者 * 或者其他數字;
  • 當前數字爲 * 時,要分上一個數字是 1 或者 2 或者 * 或者其他數字;
  • 當前數字在 [1,6] 的範圍內時, 要分上一個數字是 1 或者 2 或者 * 或者其他數字;
  • 當前數字在 [7,9] 的範圍內時, 要分上一個數字是 1 或者 2 或者 * 或者其他數字;
    具體實現如代碼所示。

實現代碼

class Solution{
    public:
        int numDecodings(string s) {
            if(s[0]=='0') return 0;
            long long pre = 1, curr = (s[0]=='*')?9:1;//dp[-1] = dp[0] = 1
            int MOD = 1e9 + 7;
            for (int i = 1; i < s.size(); i++) {
                int tmp = curr;
                if (s[i] == '0')
                    if (s[i - 1] == '1' || s[i - 1] == '2') curr = pre;
                    else if(s[i-1]=='*') curr=pre*2;
                    else return 0;
                else if(s[i]=='*'){
                    if(s[i-1]=='1') curr=(pre+curr)*9;
                    else if(s[i-1]=='2') curr=pre*6+curr*9;
                    else if(s[i-1]=='*') curr=curr*9+pre*15;
                    else curr=curr*9;
                }
                else if(s[i]>='1'&&s[i]<='6'){
                    if(s[i-1]=='1'||s[i-1]=='2') curr = curr + pre;
                    else if(s[i-1]=='*') curr=2*pre+curr;
                }
                else if(s[i]>='7'){
                    if(s[i-1]=='1'||s[i-1]=='*') curr = curr + pre;
                }
                pre = tmp;
                curr=curr%MOD;
            }
            return curr;
        }
};

參考資料

[1] Leetcode 639. 解碼方法 2
[2] Leetcode 91. 解碼方法 題解區:pris_bupt

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章