Skip to content

139. Word Break#61

Open
hayashi-ay wants to merge 8 commits intomainfrom
hayashi-ay-patch-50
Open

139. Word Break#61
hayashi-ay wants to merge 8 commits intomainfrom
hayashi-ay-patch-50

Conversation

@hayashi-ay
Copy link
Copy Markdown
Owner

return False
```

これもTLE。wordDictの文字から始まるかどうかをTrieにした。`n = len(wordDict), m = len(wordDict[i])`とするとループの部分の計算量をO(nm)からO(m)に減らせたはず。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trie 木はぎりぎりソフトウェアエンジニアの常識に含まれていないかもしれません。知っていてもマイナスになることはありません。 Computer Science Curricula 2023 Version Gamma には含まれていないようです。
https://csed.acm.org/wp-content/uploads/2023/09/Version-Gamma.pdf


Bottom Up DP
```python
class Solution:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

先頭から DP をするバージョンは書けますか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

書きました。先頭と末尾からのDPは好みの問題ですか?特段どちらかが優れているなどはないと思っています。

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        segmented = [False] * (len(s) + 1)
        segmented[0] = True
        for i in range(1, len(s) + 1):
            for word in wordDict:
                if i < len(word):
                    continue
                if not segmented[i - len(word)]:
                    continue
                if s[i - len(word):i] == word:
                    segmented[i] = True
                    break
        return segmented[-1]

```python
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
can_split = [False] * (len(s) + 1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

問題中に segmented という単語がありますので、 can_be_segmented または単に segmented としたほうが良いかもしれません。 split でも意味は通りますので、直さなければならないほどではないかもしれません。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あまり良い命名が思いつかずにsplitを使いましたがsegmented良さそうですね。ボキャブラリーについても選択肢の幅を増やしていきたいです。

for word in wordDict:
if i + len(word) > len(s):
continue
if can_split[i + len(word)] and s[i: i + len(word)] == word:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not can_split[i + len(word)]:
    continue
if s[i: i + len(word)] != word:
    continue
can_split[i] = True
break

と書いたほうが、注目している処理を後のほうに持ってくることができ、読みやすく感じます。ただ、書き換えなければならないほどではないかもしれません。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらの方が良さそうです。

for word in wordDict:
if not s.startswith(word):
continue
if self.wordBreak(s[len(word):], wordDict):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あと、スライス取るのも時間かかりますね。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。これはどういう意図のコメントですか?計算量的にはstartswithと同じだけ掛かりますね。実際にはstartswithの方が早期に打ち切れるので実際の処理的にはスライスの方が掛かりますね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ああ、これはですね、バックトラックが不要な引数であったとしても、
たとえば、("a" * 10**5, ["a"])
は文字列の構築で O(n^2) かかりますね、ということです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants