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...