Skip to content

Commit

Permalink
Solve 347 - Top K Frequent Elements (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
terenceponce authored Dec 19, 2023
1 parent 76b5c95 commit 86d256a
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ This is a monorepo containing my solutions to LeetCode problems written in vario
- 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)
- 347 - Top K Frequent Elements - [Notes](notes/0347_top_k_frequent_elements.md) | [Elixir](elixir/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.ex) | [Ruby](ruby/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.rb)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
defmodule LeetCode.Solutions.TopKFrequentElements do
@moduledoc false

@spec call(nums :: [integer], k :: integer) :: [integer]
def call(nums, k) do
nums
|> Enum.frequencies()
|> Enum.sort(fn {_num1, x}, {_num2, y} -> x >= y end)
|> Enum.take(k)
|> Enum.map(fn {num, _frequency} -> num end)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule LeetCode.Solutions.TopKFrequentElementsTest do
use ExUnit.Case, async: true

alias LeetCode.Solutions.TopKFrequentElements

test "Case 1 works" do
assert TopKFrequentElements.call([1, 1, 1, 2, 2, 3], 2) == [1, 2]
end

test "Case 2 works" do
assert TopKFrequentElements.call([1], 1) == [1]
end
end
46 changes: 46 additions & 0 deletions notes/0347_top_k_frequent_elements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Top K Frequent Elements

**Link to Problem**: https://leetcode.com/problems/top-k-frequent-elements

## Solutions

- [Elixir](../elixir/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.ex)
- [Ruby](../ruby/lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements.rb)

## Description

Given an integer array `nums` and an integer `k`, return the `k` most frequent elements. You may return the answer in **any order**.

## Examples

### Example 1

```
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
```

### Example 2

```
Input: nums = [1], k = 1
Output: [1]
```

## Approach

We produce a hash map of the frequencies of each element in the list/array. We then convert this hash map back into a list/array
and we sort the list/array based on the frequency in descending order.

Once the list/array has been sorted, we take the first `k` elements and we produce a new list/array containing the first element of
the tuple/subarray.

## Thoughts

One thing I learned from this problem is how the sorting works for both Elixir and Ruby. Apparently, they work the same way. It's
just that the syntax looks slightly different.

For example, Ruby has the spaceship operator `<=>` while Elixir has to use `<=` or `>=`.

Also, for Elixir, we can skip the step where we have to convert the hash map into a list because the `Enum` module already knows
how to iterate through a hash map.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

def top_k_frequent(nums, k_elements)
nums.tally
.to_a
.sort { |a, b| b[1] <=> a[1] }
.first(k_elements)
.map(&:first)
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

require 'test_helper'
require_relative '../../../lib/solutions/0347_top_k_frequent_elements/top_k_frequent_elements'

class TopKFrequentElementsTest < Minitest::Test
def test_case_1_works
assert_equal [1, 2], top_k_frequent([1, 1, 1, 2, 2, 3], 2)
end

def test_case_2_works
assert_equal [1], top_k_frequent([1], 1)
end
end

0 comments on commit 86d256a

Please sign in to comment.