# Leetcode Group-Anagrams

2022-09-06 16:46

> ##### Data structures:
>
> #DS #array #hash_table #two_way_hash_table
>
> ##### Difficulty:
>
> #coding_problems #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
