leetcode 91.Decode Ways

1. 題目概述

題目如下:
A message containing letters from A-Z is 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.

Input: "12"
Output: 2
Explanation: It could be decoded as "AB" (1 2) or "L" (12).

題目的中文意思是給出一個字母和數字的映射,然後給出一串數字,返回對應的合法字母序列的個數.

2. 解題思路

首先用一個例子來分析一下.假設輸入的數字是222,那麼對應的輸出結果是3.從左到右,只有2的時候對應的結果是1,22的時候對應的結果是2,分別爲

2  2-> B B
22 -> V

222對應的結果是3,分別爲

2 2 2-> B B B
22 2 -> V B
2 22 -> B V

在過程中我們可以發現

f(222) = f(22) + f(2)

所以很自然的想到動態規劃.對於第i個數字子串對應的合法字母串數目,等於第i-1個子串和i-2個子串之和,如下所示

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

接下來考慮特殊情況,假設輸出的串爲0,那麼對應的輸出應該爲0,因爲這個串無法映射到任意合法的字母串.所以我們知道,當起始字符串字母爲0時,

f[1] = 0 if(s[0] == '0')

同理,接着考慮字符串28,這數字對應的合法字符串爲1,如下所示

2 8 -> B F
28 -> None

28大於26,不對應任何字母.綜上,我們可以得出完整的動態規劃方程式

f[0] = 1
f[1] = (s[0] == '0')?0:1;
f[i] = (s[i]=='0')?0:f[i]+f[i-1]; //如果當前字母不爲0,f[i]+=f[i-1]
f[i] = (s[i-1:s[i]] is valid) ?f[i]=f[i]+f[i-2]:0;//如果s[i-1:i]可以對應合法的字符串,f[i] = f[i] + f[i-2]

3. 題目代碼

該題目的代碼如下所示

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Solution {
public:
    int numDecodings(string s) {
        if(s.size() == 0)return 0;
        if(s.size() == 1){
            if(s[0] == '0')return 0;
            else{
                return 1;
            }
        }
        vector<int> gV(s.size()+1,0);
        gV[0] = 1;
        if(s[0] == '0'){
            gV[1] = 0;
        }
        else{
            gV[1] = 1;
        }
        //for(int i=0;i<gV.size();i++)cout<<i<<" "<<gV[i]<<endl;

        for(int i=1;i<s.size();i++){
            if(s[i] != '0'){
                gV[i+1] += gV[i];
            }
            string sTemp = s.substr(i-1, 2);
            //cout<<sTemp<<endl;
            if(sTemp[0] != '0' && stoi(sTemp) > 0 && stoi(sTemp) <= 26){
                gV[i+1] += gV[i-1];
            }
        }
        return gV[s.size()];
    }
};

int main() {
    Solution se;
    cout<<se.numDecodings("")<<endl;
    cout<<se.numDecodings("01")<<endl;
    cout<<se.numDecodings("1")<<endl;
    cout<<se.numDecodings("11")<<endl;
    cout<<se.numDecodings("100")<<endl;
    cout<<se.numDecodings("226")<<endl;
    return 0;
}
發佈了10 篇原創文章 · 獲贊 0 · 訪問量 2319
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章