Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions 139/139.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
## 何も見ずに解いてみる

最初に思い浮かんだ解法で解いてみる。DPみたいにするなら、今までの文字数すべてについて分解できるかできないかがわかっていたら、そこから最終文字までの単語がwordDictに含まれているかどうかを調べればできそう。

```cpp
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> words(wordDict.begin(), wordDict.end());
unordered_set<int> visited;

Choose a reason for hiding this comment

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

型で分かると言えば分かるのですが、 visited_indices の命名とかの方がよりわかりやすいと思います。

queue<int> index_to_check;
index_to_check.push(0);
while (!index_to_check.empty()) {
int index = index_to_check.front();
index_to_check.pop();
for (int i = 1; i <= s.size() - index; ++i) {

Choose a reason for hiding this comment

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

ここの i は word_length もしくは sub_str_length かなと思いました。

Copy link
Owner Author

Choose a reason for hiding this comment

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

たしかにそちらのほうがだいぶ分かりやすくなりますね!

string new_word = s.substr(index, i);
if (words.contains(new_word)) {
int new_index = index + i;
if (new_index == s.size()) {
return true;
}
if (visited.contains(new_index)) {
continue;
}
visited.insert(new_index);
index_to_check.push(new_index);
}
}
}
return false;
}
};
```

## 他の人のコードを見てみる

https://github.com/Satorien/LeetCode/pull/39/files
https://github.com/ryosuketc/leetcode_arai60/pull/52/files
https://github.com/tokuhirat/LeetCode/pull/39/files
https://github.com/Ryotaro25/leetcode_first60/pull/43/files
https://github.com/frinfo702/software-engineering-association/pull/3/files
https://github.com/philip82148/leetcode-swejp/pull/8/files
https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%82%A4_(%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0)

C++は長いコードになるとまだ読み慣れない・・・

wordDictの中を探す方法としては辞書順に並べた2分探索も選択肢に入りそうかも。

自分がstep1で書いたような、今いるところから前方向を向いてwordDictに入っててほしいwordを調べるやり方は、候補になるword全てをwordDictの中からチェックしなきゃいけない。
それに比べると、step3のコードは分解できると分かったところから今いるところまでの部分列だけを探せばいいので多少効率的?
逆に、前方向を向いてwordDictに入ってるかチェックする場合には、目標となる文字列の後ろから始めることによってパフォーマンスが改善するかも。今いるところから分解できると分かったところまでの部分文字列を探せばいいので
(説明の助けになってるかわかりませんが下の絵みたいなことです)

<img width="1593" height="854" alt="image" src="https://github.com/user-attachments/assets/1167f5d0-9d75-40a8-bcca-f06304e828ac" />

あと、次のコード(最終コードで`substr`を呼び出すものを間違えて`s_view`ではなく`s`にしてしまっているものです)を動かすとエラーが出てなんでだろうと考えてたんですが、
`words.contains(word)`を呼び出すときにはもうすでに`word`(string_view)が見ている先の文字列が無くなってるからですかね?(違ってたら教えてください)

```cpp
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
string_view s_view(s);
unordered_set<string_view> words(wordDict.begin(), wordDict.end());
vector<int> breakable_indexes = {0};
for (int index = 1; index <= s.size(); ++index) {
for (int breakable_index : breakable_indexes) {
string_view word = s.substr(breakable_index, index - breakable_index);
if (words.contains(word)) {
breakable_indexes.push_back(index);
break;
}
}
}
return breakable_indexes.back() == s.size();
}
};
```

## 最終コード

```cpp
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
string_view s_view(s);
unordered_set<string_view> words(wordDict.begin(), wordDict.end());
vector<int> breakable_indexes = {0};
for (int index = 1; index <= s.size(); ++index) {
for (int breakable_index : breakable_indexes) {
string_view word = s_view.substr(breakable_index, index - breakable_index);
if (words.contains(word)) {
breakable_indexes.push_back(index);
break;
}

Choose a reason for hiding this comment

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

自分だったら以下のような変数名にします。

        for (int end = 1; end <= s.size(); ++end) {
            for (int start : breakable_indexes) {
                string_view sub_str = s_view.substr(start, end - start);
                if (words.contains(sub_str)) {

}
}
return breakable_indexes.back() == s.size();
}
};
```