diff --git a/0140.Word-Break-II/memo.md b/0140.Word-Break-II/memo.md new file mode 100644 index 0000000..ca74a02 --- /dev/null +++ b/0140.Word-Break-II/memo.md @@ -0,0 +1,17 @@ +# 140. Word Break II + +## step1 + +バックトラックで解く。珍しくミスなく一発で通った。 +ただし、str.startwithの引数の順番を調べた。 + +## step2 + +https://leetcode.com/problems/word-break-ii/solutions/44311/python-easy-to-understand-solution-by-yi-n05s/?envType=problem-list-v2&envId=7p5x763 + +トップダウンDFS。確かにバックトラックだと計算が重複している状況が考えられる。 + +https://leetcode.com/problems/word-break-ii/solutions/763221/python-dp-solution-explained-by-dbabiche-rhhz/?envType=problem-list-v2&envId=7p5x763 + +ボトムアップの動的計画法 + diff --git a/0140.Word-Break-II/step1.py b/0140.Word-Break-II/step1.py new file mode 100644 index 0000000..9eec06f --- /dev/null +++ b/0140.Word-Break-II/step1.py @@ -0,0 +1,17 @@ +class Solution: + def wordBreak(self, s: str, wordDict: list[str]) -> list[str]: + result = [] + broken_words = [] + + def traverse(start): + if start == len(s): + result.append(" ".join(broken_words)) + return + for word in wordDict: + if s.startswith(word, start): + broken_words.append(word) + traverse(start + len(word)) + broken_words.pop() + + traverse(0) + return result diff --git a/0140.Word-Break-II/step2_bottom_up.py b/0140.Word-Break-II/step2_bottom_up.py new file mode 100644 index 0000000..4a5c13f --- /dev/null +++ b/0140.Word-Break-II/step2_bottom_up.py @@ -0,0 +1,22 @@ +class Solution: + def wordBreak(self, s: str, wordDict: list[str]) -> list[str]: + word_set = set(wordDict) + n = len(s) + + # dp[i]: s[i:]で作れる文字列のリスト + dp = [[] for _ in range(n + 1)] + dp[n] = [""] + + for i in range(n - 1, -1, -1): + sentences = [] + for j in range(i + 1, n + 1): + word = s[i:j] + if word in word_set: + for sub in dp[j]: + if sub == "": + sentences.append(word) + else: + sentences.append(word + " " + sub) + dp[i] = sentences + + return dp[0] diff --git a/0140.Word-Break-II/step2_top_down_dfs.py b/0140.Word-Break-II/step2_top_down_dfs.py new file mode 100644 index 0000000..962a594 --- /dev/null +++ b/0140.Word-Break-II/step2_top_down_dfs.py @@ -0,0 +1,25 @@ +import functools + + +class Solution: + def wordBreak(self, s: str, wordDict: list[str]) -> list[str]: + word_set = set(wordDict) + + @functools.cache + def traverse(start): + if start == len(s): + return [""] + + result = [] + for end in range(start + 1, len(s) + 1): + word = s[start:end] + if word in word_set: + sub_sentences = traverse(end) + for sub in sub_sentences: + if sub == "": + result.append(word) + else: + result.append(word + " " + sub) + return result + + return traverse(0)