91 解碼方法 dp M

2021-10-01 01:35:55 字數 3019 閱讀 3241

91. 解碼方法

一條包含字母 a-z 的訊息通過以下方式進行了編碼:

『a』 -> 1

『b』 -> 2

…『z』 -> 26

給定乙個只包含數字的非空字串,請計算解碼方法的總數。

示例 1:

輸入: 「12」

輸出: 2

解釋: 它可以解碼為 「ab」(1 2)或者 「l」(12)。

示例 2:

輸入: 「226」

輸出: 3

解釋: 它可以解碼為 「bz」 (2 26), 「vf」 (22 6), 或者 「bbf」 (2 2 6) 。

分析:動態規劃首先是如何構建dp表,也就是如何找到子問題,像這種串的,一般都是橫豎自我展開。那分析dp該怎麼計算,也就是子問題如何進行。

首先,很容易我們想到s如果確定,那接著確定s,s…,所以子問題確定了;

那具體的dp計算呢,dp[i][j]表示其s的解碼方法的個數,一般我們先把初始行列求出來,方便後續的迭代,這裡不會用到列,所以只對第一行進行了初始計算;

dp迭代,是很有意思的,也是最不容易確定的,但只要我們能夠確定dp[i][j]的準確意義,那就好辦了,在每一行的遍歷中dp[i][j->n]表示s的解碼次數,我們需要將各個部分的解碼總數加起來;

e.g.:

以「226」為例子,初始化第一行為1,1,0表示2,22能夠解碼解且有一種解碼方法,226不能解碼;

計算dp[1][1],因為2能夠被解碼,又dp[0][0]>0表示,2之前的那一部分可被解碼,並且解碼數為dp[0][0],所以合起來,22能夠被解碼,因為dp[1][1]時,是單元素,只有一種情況,所以組合起來的解碼總數就和2之前的解碼總數一致dp[0][0];第一行dp[0][1]>0,表示22能夠被解碼,這又是一種解碼方案,解碼數為dp[0][1],所以當前22可被解碼的方法總數為dp[0][1]+dp[1][1],即就是那一類的累加和,為方便計算,我們累加下來,dp[1][1]+=dp[0][1];

計算dp[1][2],表示26能夠被解碼,那26之前的部分是2,前部分劃分總數是dp[0][0],所以dp[1][2]=dp[0][0],並將這裡列的方法總數累加下來,dp[1][2]+=dp[0][2];

同樣的方法,計算第三行,最後dp[len(s)-1][len(s)-1]即是所有的解碼總數。

所以計算公式:

當前能夠被解碼時(比如226中的2):

d p[

i][j

]=dp

[i−1

][i−

1]+d

p[i−

1][j

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

dp[i][

j]=d

p[i−

1][i

−1]+

dp[i

−1][

j]當前不能被解碼時(比如101中的0):

d p[

i][j

]+=d

p[i−

1][j

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

dp[i][

j]+=

dp[i

−1][

j]左邊例子101,是在說明題目的要求01是不能夠被解碼的。

code2:通過字元計算轉化成數字

還有一點,題目中又測試比較大的case,我這裡提交時,沒有把測試的fmt.println()刪掉,導致超時,刪除後,通過;另外之前用的時strconv.atoi將字串轉化為數字,改為字元計算轉化為數字後,速度又有所提公升。

執行結果:通過

執行用時 :8 ms, 在所有 go 提交中擊敗了23.53%的使用者

記憶體消耗 :15.7 mb, 在所有 go 提交中擊敗了6.25%的使用者

package main

import

"fmt"

func

numdecodings

(s string

)int

dp:=

make([

]int

,len

(s))

for i:=

0;i<

len(s)

;i++

tmp:=

0for i:=

0;i<

len(s)

;i++

}for i:=

1;i<

len(s)

;i++

dp[i]

[j]+=dp[i-1]

[j]}}}

return dp[

len(s)-1

][len(s)-1

]}func

main()

code1:用strconv.atoi轉化字串

執行結果:通過

執行用時 :788 ms, 在所有 go 提交中擊敗了9.80%的使用者

記憶體消耗 :79.8 mb, 在所有 go 提交中擊敗了6.25%的使用者

func

numdecodings

(s string

)int

dp:=

make([

]int

,len

(s))

for i:=

0;i<

len(s)

;i++

for i:=

0;i<

len(s)

;i++

}for i:=

1;i<

len(s)

;i++

} dp[i]

[j]+=dp[i-1]

[j]}

}return dp[

len(s)-1

][len(s)-1

]}

91 解碼方法

方法一 動態規劃法 該問題可以通過動態規劃的方法進行求解,我們假設s i 代表一條長度為i的訊息,對應的解碼方法的總數為dp i 那麼這個值的大小和dp i 1 以及dp i 2 相關,因為解碼時只有一位或者兩位字元可以作為乙個原碼看待。當我們假設這條訊息的最後一位作為原碼時,它的取值範圍為 1 9...

91 解碼方法

一條包含字母a z的訊息通過以下方式進行了編碼 a 1 b 2 z 26給定乙個只包含數字的非空字串,請計算解碼方法的總數。示例 1 輸入 12 輸出 2 解釋 它可以解碼為 ab 1 2 或者 l 12 示例 2 輸入 226 輸出 3 解釋 它可以解碼為 bz 2 26 vf 22 6 或者 b...

91 解碼方法

一條包含字母a z的訊息通過以下方式進行了編碼 a 1 b 2 z 26 給定乙個只包含數字的非空字串,請計算解碼方法的總數。示例 1 輸入 12 輸出 2解釋 它可以解碼為 ab 1 2 或者 l 12 示例 2 輸入 226 輸出 3解釋 它可以解碼為 bz 2 26 vf 22 6 或者 bb...