diff --git a/0091.Decode-Ways/memo.md b/0091.Decode-Ways/memo.md new file mode 100644 index 0000000..8d3f6f3 --- /dev/null +++ b/0091.Decode-Ways/memo.md @@ -0,0 +1,38 @@ +# 91. Decode Ways + +## step1 +DPで書いた。8mほど。配るDP。やや変数名を修正。 + +## step2 +もらうDPで書いた。この場合は2変数で管理できる。 + +LeetCodeや他の方のSolutionを見ても新しいものはないので、LLMに聞いてみるとメモ化再帰を提案された。 + +トップダウンの解法 + +```python +from functools import cache + +class Solution: + def numDecodings(self, s: str) -> int: + + @cache + def dfs(i: int) -> int: + # 文字列の最後まで到達できたら、1つの有効な分割方法が見つかったということ + if i == len(s): + return 1 + # 0から始まるデコードは存在しない + if s[i] == "0": + return 0 + + # パターン1: 1文字としてデコードする + ans = dfs(i + 1) + + # パターン2: 2文字としてデコードする + if i + 1 < len(s) and (s[i] == "1" or (s[i] == "2" and s[i+1] <= "6")): + ans += dfs(i + 2) + + return ans + + return dfs(0) +``` diff --git a/0091.Decode-Ways/step1_distribute.py b/0091.Decode-Ways/step1_distribute.py new file mode 100644 index 0000000..1480c75 --- /dev/null +++ b/0091.Decode-Ways/step1_distribute.py @@ -0,0 +1,23 @@ +class Solution: + def numDecodings(self, s: str) -> int: + if not s or s[0] == "0": + return 0 + + dp = [0] * (len(s) + 1) + dp[0] = 1 + + for i in range(len(s)): + if s[i] == "0": + continue + dp[i+1] += dp[i] + if i + 1 < len(s) and int(s[i:i+2]) <= 26: + dp[i+2] += dp[i] + + return dp[-1] + + +# solution = Solution() +# print(solution.numDecodings("12")) +# print(solution.numDecodings("226")) +# print(solution.numDecodings("0")) +# print(solution.numDecodings("1001")) diff --git a/0091.Decode-Ways/step1_distribute_revised.py b/0091.Decode-Ways/step1_distribute_revised.py new file mode 100644 index 0000000..9a7e7ca --- /dev/null +++ b/0091.Decode-Ways/step1_distribute_revised.py @@ -0,0 +1,23 @@ +class Solution: + def numDecodings(self, s: str) -> int: + if not s or s[0] == "0": + return 0 + + num_ways = [0] * (len(s) + 1) + num_ways[0] = 1 + + for i in range(len(s)): + if s[i] == "0": + continue + num_ways[i+1] += num_ways[i] + if i + 1 < len(s) and int(s[i:i+2]) <= 26: + num_ways[i+2] += num_ways[i] + + return num_ways[-1] + + +# solution = Solution() +# print(solution.numDecodings("12")) +# print(solution.numDecodings("226")) +# print(solution.numDecodings("0")) +# print(solution.numDecodings("1001")) diff --git a/0091.Decode-Ways/step2_receive.py b/0091.Decode-Ways/step2_receive.py new file mode 100644 index 0000000..e0cea30 --- /dev/null +++ b/0091.Decode-Ways/step2_receive.py @@ -0,0 +1,25 @@ +class Solution: + def numDecodings(self, s: str) -> int: + if not s or s[0] == "0": + return 0 + + num_end_with_i_minus_2 = 1 # 空文字列 + num_end_with_i_minus_1 = 1 # 最初の1文字 + + for i in range(1, len(s)): + num_end_with_i = 0 + + if s[i] != "0": + num_end_with_i += num_end_with_i_minus_1 + + if s[i-1] != "0" and 10 <= int(s[i-1:i+1]) <= 26: + num_end_with_i += num_end_with_i_minus_2 + + if num_end_with_i == 0: + return 0 + + num_end_with_i_minus_2 = num_end_with_i_minus_1 + num_end_with_i_minus_1 = num_end_with_i + + return num_end_with_i_minus_1 +