-
Notifications
You must be signed in to change notification settings - Fork 0
Create 49. Group Anagrams #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/description/) | ||
|
|
||
| ## Step1 | ||
| ### 問題意図の考察 | ||
| - 問題文の確認 | ||
| * Anagramsをグループ化せよ。という問題 | ||
| * アナグラム->同じ文字を同じ数保持している. よって、文字列をソートしてabcd順にするとkey | ||
| * このkeyをまとめて分類 | ||
|
|
||
| - 制約の確認 | ||
| 1. 1 <= strs.length <= 10^4 | ||
| * 文字列最大10^4(10,000), O(N^2)の時、10^8回(1億) 計算量は、O(N * 何か)程度だといいかな | ||
| 2. 0 <= strs[i].length <= 100 | ||
| * strs[i].length = i番目の文字列の長さ(文字数) | ||
| * つまり、0~100文字以内で、空文字もある | ||
| * 最大: 10^4 * 100 = 10^6 なので、ソート or カウントしても間に合いそう | ||
| 3. strs[i] consists of lowercase English letters. | ||
| * strs[i]は、英小文字のみ | ||
| * 26文字 | ||
| * 他の文字は考慮しなくて良さそう | ||
|
|
||
| ### 解法を考える。 | ||
| - 文字列をソートして、keyを作成する | ||
| - keyをカウント&グループ化 | ||
| - 同じものは、分類 | ||
|
|
||
| - 配列の配列というものが書いたことがなく混乱してしまった、冒頭で答えを見る。慣れていきたい。 | ||
|
|
||
| 初回の回答 | ||
| ```cpp | ||
| #include <algorithm> | ||
| #include <unordered_map> | ||
| #include <vector> | ||
| #include <string> | ||
|
|
||
| class Solution { | ||
| public: | ||
| std::vector<std::vector<std::string> > groupAnagrams(std::vector<std::string>& strs) { | ||
| std::unordered_map<std::string, std::vector<std::string> > groups; | ||
| for (const std::string& s : strs) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for (const auto& s : strs) {のほうがシンプルだと思います。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nodchip for (const auto& s : strs) {
の方が読みやすいかもしれないですね。 |
||
| std::string key = s; | ||
| std::sort(key.begin(), key.end()); | ||
| groups[key].push_back(s); | ||
| } | ||
|
|
||
| std::vector<std::vector<std::string> > result; | ||
| result.reserve(groups.size()); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reserve() をすることにより、あらかじめ必要な要素数分のメモリを確保し、 push_back() 中のメモリの再確保を避けることができるのですが、その効果が十分かどうかは計測してみないと何とも言えません。処理時間に対する要求を考慮し、シビアでない場合、 コードをシンプルにするため、reserve() を呼び出さないほうがよい場合もあると思います。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nodchip |
||
| for (auto& entry : groups) { | ||
| result.push_back(std::move(entry.second)); | ||
| } | ||
| return result; | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
| 模範回答 | ||
| ```cpp | ||
| ``` | ||
| ### コメント | ||
|
|
||
| ## Step2 | ||
| - 今回は英小文字しか出現しないが、 それ以外が出た時の対処も考えておきたい。 | ||
| - ドキュメントの確認・気になったところ | ||
| 1. std::vector (push_back / reserve / size) | ||
| * https://en.cppreference.com/w/cpp/container/vector.html | ||
| * https://en.cppreference.com/w/cpp/container/vector/push_back | ||
| * https://en.cppreference.com/w/cpp/container/vector/reserve | ||
| * https://en.cppreference.com/w/cpp/container/vector/size | ||
| 2. std::unordered_map ハッシュマップ | ||
| * https://en.cppreference.com/w/cpp/container/unordered_map.html | ||
| * https://en.cppreference.com/w/cpp/container/unordered_map/operator_at | ||
| 3. for (auto& x : container) | ||
| * https://en.cppreference.com/w/cpp/language/range-for.html | ||
| - 他の方のコード | ||
| * https://github.com/nktr-cp/leetcode/pull/13/commits/f1d09d3f5d201aa096e53824affbc11fa260a46a | ||
| * https://github.com/Ryotaro25/leetcode_first60/pull/13/commits/2416b565cd8a2a983b8cab3543d1b0d32dbc4649#diff-f08ab28ba7826a9f3d22cb94b7e24009a629a8e4212261d33183da905119b247 | ||
| -> https://github.com/Ryotaro25/leetcode_first60/pull/13/commits/2416b565cd8a2a983b8cab3543d1b0d32dbc4649#r1665235074 | ||
| -> sorted_to_group / group_anagrams という命名 | ||
| * unordered_map<string, vector<string>> の中身の確認 | ||
| ```cpp | ||
| entry.first → "aet" | ||
| entry.second → ["eat", "tea", "ate"] | ||
|
|
||
| entry.first → "ant" | ||
| entry.second → ["tan", "nat"] | ||
|
|
||
| entry.first → "abt" | ||
| entry.second → ["bat"] | ||
|
|
||
| ``` | ||
| * マップキーと値の関係の理解ができた | ||
|
|
||
| ```cpp | ||
| #include <algorithm> | ||
| #include <unordered_map> | ||
| #include <vector> | ||
| #include <string> | ||
|
|
||
| class Solution { | ||
| public: | ||
| std::vector<std::vector<std::string> > groupAnagrams(std::vector<std::string>& strs) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 非const参照で受け取ると変更の可能性があることを呼び出し側は考慮することになるので、内部で変更をしないのであればconstをつけてもよいかと思います。 |
||
| std::unordered_map<std::string, std::vector<std::string> > groups; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なにをキーにしてグループをまとめているかの情報が後を読まないとわからないので、sorted_str_to_groups(sorted_str_to_anagramsなど)くらいでもよいかなと思いました。 |
||
| for (const std::string& word : strs) { | ||
| std::string key = word; | ||
| std::sort(key.begin(), key.end()); | ||
| groups[key].push_back(s); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sではなくwordでしょうか。 |
||
| } | ||
|
|
||
| std::vector<std::vector<std::string> > result; | ||
| result.reserve(groups.size()); | ||
| for (auto& entry : groups) { | ||
| result.push_back(std::move(entry.second)); | ||
| } | ||
| return result; | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| ## Step3 | ||
| 1. 10min | ||
| 2. 9min | ||
| 3. 6min | ||
| 4. 5min | ||
| 5. 5min | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++11 以降
>と>のあいだにスペースを空けなくて済むようになっています。スペースを消すことをおすすめします。https://cpprefjp.github.io/lang/cpp11/right_angle_brackets.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nodchip
コメントありがとうございます。
こちら確認不足でした。一読しておきます。