notes/OJ notes/pages/Leetcode Group-Anagrams.md

141 lines
2.6 KiB
Markdown
Raw Normal View History

2022-09-06 16:52:42 +08:00
# Leetcode Group-Anagrams
2022-09-06 16:46
> ##### Data structures:
>
2022-09-06 17:14:03 +08:00
> #DS #array #hash_table #two_way_hash_table
2022-09-06 16:52:42 +08:00
>
> ##### Difficulty:
>
2022-09-06 20:22:48 +08:00
> #coding_problem #difficulty_medium
2022-09-06 16:52:42 +08:00
>
> ##### Additional tags:
>
2022-09-06 20:22:48 +08:00
> #leetcode
2022-09-06 16:52:42 +08:00
>
> ##### Revisions:
>
> N/A
##### Links:
- [Link to problem](https://leetcode.com/problems/group-anagrams/)
---
### Problem
Given an array of strings `strs`, group **the anagrams** together. You can return the answer in **any order**.
An **Anagram** is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
#### Examples
**Example 1:**
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
**Input:** strs = ["eat","tea","tan","ate","nat","bat"]
**Output:** [["bat"],["nat","tan"],["ate","eat","tea"]]
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
**Example 2:**
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
**Input:** strs = [""]
**Output:** [[""]]
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
**Example 3:**
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
**Input:** strs = ["a"]
**Output:** [["a"]]
2022-09-06 17:14:03 +08:00
```
2022-09-06 16:52:42 +08:00
#### Constraints
2022-09-06 20:22:48 +08:00
- `1 <= strs.length <= 104`
- `0 <= strs[i].length <= 100`
- `strs[i]` consists of lowercase English letters.
2022-09-06 16:52:42 +08:00
### Thoughts
> [!summary]
> This is a #hash_table problem.
2022-09-06 17:14:03 +08:00
#### Two way hash table
2022-09-06 20:22:48 +08:00
This one can be solved simply using two-way hash tables,
2022-09-06 17:14:03 +08:00
consisting of two hash tables:
2022-09-06 20:22:48 +08:00
2022-09-06 16:52:42 +08:00
- ana2id: turn anagram into an id
- id2str: turn id into strings that has the anagrams
The one problem is hashing vectors / arrays. Here we use
CPP-style initialization of C's array.
> [!tip]
> CPP-style initialization of C array #tip
2022-09-06 20:22:48 +08:00
>
2022-09-06 16:52:42 +08:00
> ```cpp
> array<int, 26> ana = {};
> ```
Note that vectors doesn't work in unordered hash maps,
unless we use custom hash functions.
2022-09-06 20:22:48 +08:00
And arrays in c style definition (`int arr[26];`) will be
2022-09-06 17:42:00 +08:00
hashed according to address, not conte`nt.
2022-09-06 17:14:03 +08:00
#### Alternative method
2022-09-06 20:22:48 +08:00
By using sorted strings as keys, we can also solve this
2022-09-06 17:14:03 +08:00
problem.
Since the input is lowercase English letters, counting
sort can be used.
2022-09-06 16:52:42 +08:00
### Solution
2022-09-06 17:14:03 +08:00
Two way hash table
2022-09-06 16:52:42 +08:00
```cpp
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string> &strs) {
// using to hash maps for 2-way conversion
map<array<int, 26>, int> ana2id;
// this one is the answer returned.
vector<vector<string>> id2str;
int id = 0;
for (string str : strs) {
// Use aggregate initialization to default to 0.
array<int, 26> ana = {};
for (char s : str) {
ana[s - 'a']++;
}
if (ana2id.find(ana) == ana2id.end()) {
// Not in the map.
ana2id[ana] = id;
id2str.push_back({});
id2str.back().push_back(str);
id++;
} else {
// in the map, append it to id2str
id2str[ana2id[ana]].push_back(str);
}
}
return id2str;
}
};
2022-09-06 17:14:03 +08:00
```
Counting sort
2022-09-06 20:22:48 +08:00
#TODO: solve using counting sort