【算法】Decode Ways II 解碼方式2

題目

A message containing letters from A-Z is being encoded to numbers using the following mapping way:

'A' -> 1
'B' -> 2
...
'Z' -> 26
Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers from 1 to 9.

Given the encoded message containing digits and the character '*', return the total number of ways to decode it.

Also, since the answer may be very large, you should return the output mod 109 + 7.

Example 1:
Input: ""
Output: 9
Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I".
Example 2:
Input: "1
"
Output: 9 + 9 = 18
Note:
The length of the input string will fit in range [1, 105].
The input string will only contain the character '*' and digits '0' - '9'.

編碼方式如下:

  • 1 ~ 26 分別映射 "A" ~ "Z"
  • "*" 可以代指 0 ~ 9

給出一組長度為 [1,105] 的數字字符串把曼,求可以有多少種解碼方式线梗。

解題思路

一個數字字符串燎竖,如果只考慮 0 ~ 9,沒有 * ,則編碼方式只有一種唉匾,在本題中由于將范圍擴大到了 [1,26],且還有 * 插入,所以我們只需要針對字符串中的 1 剧浸、2、*進行針對處理即可矗钟。
以 6219 為例唆香,62 和 621 分別有 1、2
假設當前字符串 sub[0,n-1] 吨艇、 sub[0,n] 有 i躬它、j 種編碼方式,若 sub[0,n] 的末尾字符為 1 东涡,則 sub[0,n+1] 計算時可分為兩種情況(sub[0,n+1] 的末尾字符為 subn+1):

  1. subn+1 單獨進行解碼時冯吓,編碼方式有 j 種
  2. subn+1 與 subn 進行合并解碼時倘待,編碼方式有 i 種

所以 sub[0,n+1] = j + i = str[0,n] + str[0,n-1]。

在此基礎上需要做一些區(qū)分的注意:

  1. 若subn+1 為 0 组贺,則只能與 subn 進行合并解碼延柠,不能單獨解碼。
  2. subn == 1锣披,2 時贞间,subn+1 在 [0,9],[0,6] 范圍內雹仿,才能與 subn 進行合并解碼增热。
  3. subn == * 時,由于 * 代指 [0,9]胧辽,所以 subn+1 單獨解碼的方式 9 倍峻仇,合并解碼時, 位數為 1 時解碼方式 9 倍邑商,尾數為 2 時解碼方式 6 倍摄咆。

代碼實現

Runtime: 100 ms
Memory: 20.5 MB

func numDecodings(_ s: String) -> Int {
        //字符串一共有多少種解碼方式
        var e0:Int64 = 1
        //存儲字符串末位為 1 時的編碼方式數量
        var e1:Int64 = 0
        //存儲字符串末位為 1 時的編碼方式數量
        var e2:Int64 = 0
        //臨時計算用的容器
        var f0:Int64 = 0
        //模的除數
        let M:Int64 = Int64(1e9 + 7)
        //遍歷字符串 s
        for c in s
        {
            if c == "*"
            {
                //由于 * 可以代指 1 ~ 9
                //所以 e0 和 e1 都有九種方式,而最大到 26 所以 e2 只有 6 種
                f0 = 9 * e0 + 9 * e1 + 6 * e2
                //由于 * 可以代指 1 和 2人断,所以 e1 和 e2 都需要賦值
                e1 = e0
                e2 = e0
            }
            else
            {
                //先計算合并解碼的情況
                //當前一位為 1 時吭从,當前位在[0,9]范圍內都可以進行合并解碼,所以將 e1 加入到容器
                f0 = e1
                //當前一位為 2 時恶迈,當前位在[0,6]范圍內才可以進行合并解碼涩金,將 e2 加入到容器
                if c <= "6"
                {
                    f0 += e2
                }
                
                //計算單獨解碼
                //如果當前字符為 0 ,則不能進行單獨解碼
                //所以只有當前位在[1,9]范圍內才可以單獨解碼暇仲,將 e0 加入到容器
                if c > "0"
                {
                    f0 += e0
                }
                //依據當前字符是否為 1 或 2 步做,來判斷是將 e1 e2 為 e0 還是 0
                //以 61616 為例,當循環(huán)到 6161 時奈附,當前字符為 1
                //在下次遍歷到 6 時全度,由于會用到 616 和 6161 的結果
                //所以在此次遍歷中,將 e0 賦值給 e1
                //這樣斥滤,e1 中保留的就是 616 的結果将鸵,而 6161 的結果可在之后通過 f0 進行計算存儲到 e0 中
                //當前字符不為 1 時,則下次遍歷不會出現變動中跌,故將 e1 變更為 0
                // e2 也是相同道理
                e1 = c == "1" ? e0 : 0
                e2 = c == "2" ? e0 : 0
            }
            //本次循環(huán)中咨堤,用 f0 % M 得出結果 e0
            e0 = f0 % M
        }
        //返回結果
        return Int(e0)
    }

代碼地址:https://github.com/sinianshou/EGSwiftLearning

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漩符,隨后出現的幾起案子一喘,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凸克,死亡現場離奇詭異议蟆,居然都是意外死亡,警方通過查閱死者的電腦和手機萎战,發(fā)現死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門咐容,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蚂维,你說我怎么就攤上這事戳粒。” “怎么了虫啥?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵蔚约,是天一觀的道長。 經常有香客問我涂籽,道長苹祟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任评雌,我火速辦了婚禮树枫,結果婚禮上,老公的妹妹穿的比我還像新娘景东。我一直安慰自己砂轻,他們只是感情好,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布耐薯。 她就那樣靜靜地躺著舔清,像睡著了一般丝里。 火紅的嫁衣襯著肌膚如雪曲初。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天杯聚,我揣著相機與錄音臼婆,去河邊找鬼。 笑死幌绍,一個胖子當著我的面吹牛颁褂,可吹牛的內容都是我干的。 我是一名探鬼主播傀广,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼颁独,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了伪冰?” 一聲冷哼從身側響起誓酒,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后靠柑,有當地人在樹林里發(fā)現了一具尸體寨辩,經...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年歼冰,在試婚紗的時候發(fā)現自己被綠了靡狞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡隔嫡,死狀恐怖甸怕,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情腮恩,我是刑警寧澤蕾各,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站庆揪,受9級特大地震影響式曲,放射性物質發(fā)生泄漏。R本人自食惡果不足惜缸榛,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一吝羞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧内颗,春花似錦钧排、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至找前,卻和暖如春糟袁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躺盛。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工项戴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人槽惫。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓周叮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親界斜。 傳聞我的和親對象是個殘疾皇子仿耽,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容