diff --git a/49/49. Group Anagrams.md b/49/49. Group Anagrams.md new file mode 100644 index 0000000..1ede5a7 --- /dev/null +++ b/49/49. Group Anagrams.md @@ -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 +#include +#include +#include + +class Solution { + public: + std::vector > groupAnagrams(std::vector& strs) { + std::unordered_map > groups; + for (const std::string& s : strs) { + std::string key = s; + std::sort(key.begin(), key.end()); + groups[key].push_back(s); + } + + std::vector > result; + result.reserve(groups.size()); + 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> の中身の確認 + ```cpp + entry.first → "aet" + entry.second → ["eat", "tea", "ate"] + + entry.first → "ant" + entry.second → ["tan", "nat"] + + entry.first → "abt" + entry.second → ["bat"] + + ``` + * マップキーと値の関係の理解ができた + +```cpp +#include +#include +#include +#include + +class Solution { + public: + std::vector > groupAnagrams(std::vector& strs) { + std::unordered_map > groups; + for (const std::string& word : strs) { + std::string key = word; + std::sort(key.begin(), key.end()); + groups[key].push_back(s); + } + + std::vector > 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