141 lines
2.6 KiB
Markdown
141 lines
2.6 KiB
Markdown
# Leetcode Group-Anagrams
|
|
|
|
2022-09-06 16:46
|
|
|
|
> ##### Data structures:
|
|
>
|
|
> #DS #array #hash_table #two_way_hash_table
|
|
>
|
|
> ##### Difficulty:
|
|
>
|
|
> #coding_problem #difficulty_medium
|
|
>
|
|
> ##### Additional tags:
|
|
>
|
|
> #leetcode
|
|
>
|
|
> ##### 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:**
|
|
|
|
```
|
|
**Input:** strs = ["eat","tea","tan","ate","nat","bat"]
|
|
**Output:** [["bat"],["nat","tan"],["ate","eat","tea"]]
|
|
```
|
|
|
|
**Example 2:**
|
|
|
|
```
|
|
**Input:** strs = [""]
|
|
**Output:** [[""]]
|
|
```
|
|
|
|
**Example 3:**
|
|
|
|
```
|
|
**Input:** strs = ["a"]
|
|
**Output:** [["a"]]
|
|
```
|
|
|
|
#### Constraints
|
|
|
|
- `1 <= strs.length <= 104`
|
|
- `0 <= strs[i].length <= 100`
|
|
- `strs[i]` consists of lowercase English letters.
|
|
|
|
### Thoughts
|
|
|
|
> [!summary]
|
|
> This is a #hash_table problem.
|
|
|
|
#### Two way hash table
|
|
|
|
This one can be solved simply using two-way hash tables,
|
|
consisting of two hash tables:
|
|
|
|
- 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
|
|
>
|
|
> ```cpp
|
|
> array<int, 26> ana = {};
|
|
> ```
|
|
|
|
Note that vectors doesn't work in unordered hash maps,
|
|
unless we use custom hash functions.
|
|
|
|
And arrays in c style definition (`int arr[26];`) will be
|
|
hashed according to address, not conte`nt.
|
|
|
|
#### Alternative method
|
|
|
|
By using sorted strings as keys, we can also solve this
|
|
problem.
|
|
|
|
Since the input is lowercase English letters, counting
|
|
sort can be used.
|
|
|
|
### Solution
|
|
|
|
Two way hash table
|
|
|
|
```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;
|
|
}
|
|
};
|
|
```
|
|
|
|
Counting sort
|
|
|
|
#TODO: solve using counting sort
|