387.first unique character in a string#15
Conversation
| } | ||
| } | ||
| int min_index = INT_MAX; | ||
| for (const auto& [key, val] : char_to_index) { |
There was a problem hiding this comment.
普通にchar,indexで良かったですね。
gemini見つつここは書いたのであまり気が遣えていませんでした。
| public: | ||
| int firstUniqChar(string s) { | ||
| unordered_map<char, int> char_to_index; | ||
| unordered_set<char> overraps; |
There was a problem hiding this comment.
overlapですかね。この問題での重複を表す単語としては不自然な気がしました。
There was a problem hiding this comment.
普通にduplicatesとseenなどでよかったですね。
| unordered_setですでに現れた文字を記録することを考えたが、返り値インデックスの要求に対してその情報を保持できない。 | ||
|
|
||
| よくよく考えるとstring型には元々find()メソッドがあることを思い出した。昨日の問題で重厚なcpp版split関数を書いていた方のコードから学んだことだ。 | ||
| じゃあそもそもhashtableを使う必要すらない。後ろからの探索と前からの探索がぶつかればそれが単独だから、そのインデックスを返せばよい。 |
There was a problem hiding this comment.
レビューありがとうございます。
この場合、空間計算量を考えてアイデアに飛びついてしまったような形です。
時間計算量はあまり考えられていません。
| if (!char_to_index.contains(s[i])) { | ||
| char_to_index[s[i]] = i; | ||
| } else { | ||
| char_to_index.erase(s[i]); |
There was a problem hiding this comment.
重複を表す特殊な値をchar_to_indexに入れておくと、overrapsをなくせそうですかね。
There was a problem hiding this comment.
なるほど、-1などを入れておくということですね。
思いつきませんでした。ありがとうございます。
| } | ||
| } | ||
| int min_index = INT_MAX; | ||
| for (const auto& [key, val] : char_to_index) { |
There was a problem hiding this comment.
こちらのコメントをご参照ください。
hemispherium/LeetCode_Arai60#10 (comment)
| overraps.insert(s[i]); | ||
| } | ||
| } | ||
| int min_index = INT_MAX; |
There was a problem hiding this comment.
C++11 以降であれば、 std::numeric_limits::max() を使用したほうがモダンに感じます。
|
|
||
| // 2. 高速検索のためのハッシュマップ | ||
| // 【ポイント】値の代わりに、リスト内の「住所(イテレータ)」を記憶する! | ||
| std::unordered_map<std::string, std::list<std::pair<std::string, int>>::iterator> hash_map; |
There was a problem hiding this comment.
unordered_map がハッシュマップで実装されるかどうかは、 C++ の規格では決まっていません。 C++ の規格では、時間計算量のみが規定されています。
https://timsong-cpp.github.io/cppwp/n4950/unord.map
一方、ほとんどの実装ではハッシュテーブルが使われると思います。
There was a problem hiding this comment.
レビューありがとうございます。
てっきりハッシュマップ=unordered_set, unordered_mapだと思っていました。
他の方のRPでもハッシュマップと書く方が少なかったように感じます。
勉強になりました。
|
|
||
| // 2. 高速検索のためのハッシュマップ | ||
| // 【ポイント】値の代わりに、リスト内の「住所(イテレータ)」を記憶する! | ||
| std::unordered_map<std::string, std::list<std::pair<std::string, int>>::iterator> hash_map; |
There was a problem hiding this comment.
変数名に型名を入れても、読み手にとってあまり情報が増えないように思います。キーと値にそれぞれどのようなものが含まれているかが分かる名前が良いと思います。ただ、今回は値にリストへのイテレーターが入るため、難しい所です。 key_to_list_iterator あたりでしょうか。
| // データの挿入 (put) | ||
| void put(const std::string& key, int value) { | ||
| // すでに同じキーがある場合は、古い住所のデータをリストから消す(重複防止) | ||
| if (hash_map.find(key) != hash_map.end()) { |
There was a problem hiding this comment.
if (hash_map.contains(key)) {のほうがシンプルだと思いました。
あるいは処理の重複を避けるため、イテレーターを使いまわす書き方も良いと思いました。
auto it = hash_map.find(key);
if (it != hash_map.end()) {
order_list.erase(it);
}There was a problem hiding this comment.
ありがとうございます。
containsの方がわかりやすく簡潔ですね。
なるほど、イテレータを使いまわさない場合、ハッシュ関数を再度呼び出すことになりますね。
This problem: https://leetcode.com/problems/first-unique-character-in-a-string/description/
Next problem: https://leetcode.com/problems/subarray-sum-equals-k/description/