Skip to content

Commit

Permalink
Solve 49 - Group Anagrams
Browse files Browse the repository at this point in the history
  • Loading branch information
terenceponce committed Dec 19, 2023
1 parent 0652b4c commit e4d9f2e
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ This is a monorepo containing my solutions to LeetCode problems written in vario
## List of Problems/Solutions

- 1 - Two Sum - [Notes](notes/0001_two_sum.md) | [Elixir](elixir/lib/solutions/0001_two_sum/two_sum.ex) | [Ruby](ruby/lib/solutions/0001_two_sum/two_sum.rb)
- 49 - Group Anagrams - [Notes](notes/0049_group_anagrams.md) | [Elixir](elixir/lib/solutions/0049_group_anagrams/group_anagrams.ex) | [Ruby](ruby/lib/solutions/0049_group_anagrams/group_anagrams.rb)
- 217 - Contains Duplicate - [Notes](notes/0217_contains_duplicate.md) | [Elixir](elixir/lib/solutions/0217_contains_duplicate/contains_duplicate.ex) | [Ruby](ruby/lib/solutions/0217_contains_duplicate/contains_duplicate.rb)
- 242 - Valid Anagram - [Notes](notes/0242_valid_anagram.md) | [Elixir](elixir/lib/solutions/0242_valid_anagram/valid_anagram.ex) | [Ruby](ruby/lib/solutions/0242_valid_anagram/valid_anagram.rb)
14 changes: 14 additions & 0 deletions elixir/lib/solutions/0049_group_anagrams/group_anagrams.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
defmodule LeetCode.Solutions.GroupAnagrams do
@moduledoc false

@spec call(strs :: [String.t()]) :: [[String.t()]]
def call(strs) do
strs
|> Enum.group_by(fn word ->
word
|> String.graphemes()
|> Enum.sort()
end)
|> Map.values()
end
end
26 changes: 26 additions & 0 deletions elixir/test/solutions/0049_group_anagrams/group_anagrams.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule LeetCode.Solutions.GroupAnagramsTest do
use ExUnit.Case, async: true

alias LeetCode.Solutions.GroupAnagrams

test "Case 1 works" do
input = ["eat", "tea", "tan", "ate", "nat", "bat"]
expected_output = [["bat"], ["eat", "tea", "ate"], ["tan", "nat"]]

assert GroupAnagrams.call(input) == expected_output
end

test "Case 2 works" do
input = [""]
expected_output = [[""]]

assert GroupAnagrams.call(input) == expected_output
end

test "Case 3 works" do
input = ["a"]
expected_output = [["a"]]

assert GroupAnagrams.call(input) == expected_output
end
end
62 changes: 62 additions & 0 deletions notes/0049_group_anagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Group Anagrams

**Link to Problem**: https://leetcode.com/problems/group-anagrams

## Solutions

- [Elixir](../elixir/lib/solutions/0049_group_anagrams/group_anagrams.ex)
- [Ruby](../ruby/lib/solutions/0049_group_anagrams/group_anagrams.rb)

## Description

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"]]
```

## Approach

The clue for this problem is that we are asked to group the anagrams together and that we have
to product a nested array for the output.

This means that we can make use of the language's `group_by` method/function which produces a
hash map based on the grouping criteria that we pass into it.

Since this is an anagram problem, we just repeat the same solution as
[242 - Valid Anagram](0242_valid_anagram.md) where we determine anagrams by sorting the characters
of a given string.

Once we get the hash map, we just output the values of the hash map without the keys.

## Additional Thoughts

This is a medium problem, but I only got here because it was part of the build up for Blind 75.

The progression to get to this problem is pretty good because I at least had some idea on how to
solve this.

Of course, I didn't actually figure out the solution for this on my own and I had to look it up.
5 changes: 5 additions & 0 deletions ruby/lib/solutions/0049_group_anagrams/group_anagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

def group_anagrams(strs)
strs.group_by { |str| str.chars.sort }.values
end
21 changes: 21 additions & 0 deletions ruby/test/solutions/0049_group_anagrams/group_anagrams_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require 'test_helper'
require_relative '../../../lib/solutions/0049_group_anagrams/group_anagrams'

class GroupAnagramsTest < Minitest::Test
def test_case_1_works
input = %w[eat tea tan ate nat bat]
expected_output = [%w[eat tea ate], %w[tan nat], %w[bat]]

assert_equal expected_output, group_anagrams(input)
end

def test_case_2_works
assert_equal [['']], group_anagrams([''])
end

def test_case_3_works
assert_equal [['a']], group_anagrams(['a'])
end
end

0 comments on commit e4d9f2e

Please sign in to comment.