Skip to content

Commit 2c6ceeb

Browse files
authored
Solve 2068 - Check Whether Two Strings Are Almost Equivalent (#28)
1 parent 18a11a7 commit 2c6ceeb

File tree

4 files changed

+117
-0
lines changed

4 files changed

+117
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ mix test
3030
- [1207 - Unique Number of Occurrences](lib/solutions/01207_unique_number_of_occurrences)
3131
- [1365 - How Many Numbers Are Smaller Than The Current Number](lib/solutions/01365_how_many_numbers_are_smaller_than_the_current_number)
3232
- [1512 - Number of Good Pairs](lib/solutions/01512_number_of_good_pairs)
33+
- [2068 - Check Whether Two Strings Are Almost Equivalent](lib/solutions/02068_check_whether_two_strings_are_almost_equivalent)
3334

3435
#### Medium
3536

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Check Whether Two Strings are Almost Equivalent
2+
3+
**Link to Problem**: https://leetcode.com/problems/check-whether-two-strings-are-almost-equivalent
4+
5+
## Description
6+
7+
Two strings `word1` and `word2` are considered **almost equivalent** if the differences between the frequencies of each letter from `'a'` to `'z'` between `word1` and `word2` is at **most** `3`.
8+
9+
Given two strings `word1` and `word2`, each of length `n`, return `true` if `word1` and `word2` are **almost equivalent**, or `false` otherwise.
10+
11+
The frequency of a letter `x` is the number of times it occurs in the string.
12+
13+
## Examples
14+
15+
### Example 1
16+
17+
```
18+
Input: word1 = "aaaa", word2 = "bccb"
19+
Output: false
20+
Explanation: There are 4 'a's in "aaaa" but 0 'a's in "bccb".
21+
The difference is 4, which is more than the allowed 3.
22+
```
23+
24+
### Example 2
25+
26+
```
27+
Input: word1 = "abcdeef", word2 = "abaaacc"
28+
Output: true
29+
Explanation: The differences between the frequencies of each letter in word1 and word2 are at most 3:
30+
- 'a' appears 1 time in word1 and 4 times in word2. The difference is 3.
31+
- 'b' appears 1 time in word1 and 1 time in word2. The difference is 0.
32+
- 'c' appears 1 time in word1 and 2 times in word2. The difference is 1.
33+
- 'd' appears 1 time in word1 and 0 times in word2. The difference is 1.
34+
- 'e' appears 2 times in word1 and 0 times in word2. The difference is 2.
35+
- 'f' appears 1 time in word1 and 0 times in word2. The difference is 1.
36+
```
37+
38+
### Example 3
39+
40+
```
41+
Input: word1 = "cccddabba", word2 = "babababab"
42+
Output: true
43+
Explanation: The differences between the frequencies of each letter in word1 and word2 are at most 3:
44+
- 'a' appears 2 times in word1 and 4 times in word2. The difference is 2.
45+
- 'b' appears 2 times in word1 and 5 times in word2. The difference is 3.
46+
- 'c' appears 3 times in word1 and 0 times in word2. The difference is 3.
47+
- 'd' appears 2 times in word1 and 0 times in word2. The difference is 2.
48+
```
49+
50+
## Thoughts
51+
52+
Initially thought I should use `Enum.frequencies()` on both words and compare, but then I would
53+
have to do another loop to compare the difference between each hash maps, so I didn't go for it.
54+
55+
I ended up just initializing a blank hash map and looping through each word to count the occurrences
56+
of each character. The loop on the first word will count positively on each character and the loop
57+
on the second word will count negatively on each character.
58+
59+
Once we get a resulting hash map from counting both words, we will filter the hash map to remove
60+
any frequencies that are below `4` and return `false` if the filtered hash map still has data
61+
inside it and `true` if otherwise.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
defmodule LeetCodePractice.Solutions.CheckWhetherTwoStringsAreAlmostEquivalent do
2+
@moduledoc """
3+
Two strings `word1` and `word2` are considered **almost equivalent** if the differences between the frequencies of each letter from `'a'` to `'z'` between `word1` and `word2` is at **most** `3`.
4+
5+
Given two strings `word1` and `word2`, each of length `n`, return `true` if `word1` and `word2` are **almost equivalent**, or `false` otherwise.
6+
7+
The frequency of a letter `x` is the number of times it occurs in the string.
8+
"""
9+
10+
@spec call(word1 :: String.t(), word2 :: String.t()) :: boolean
11+
def call(word1, word2) when byte_size(word1) == byte_size(word2) do
12+
%{}
13+
|> count_frequencies(word1, 1)
14+
|> count_frequencies(word2, -1)
15+
|> Enum.filter(fn {_, val} -> abs(val) > 3 end)
16+
|> Enum.any?()
17+
|> Kernel.not()
18+
end
19+
20+
def call(_, _), do: false
21+
22+
defp count_frequencies(map, word, increment) do
23+
word
24+
|> String.downcase()
25+
|> String.graphemes()
26+
|> Enum.reduce(map, fn char, map ->
27+
Map.update(map, char, increment, &(&1 + increment))
28+
end)
29+
end
30+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
defmodule LeetCodePractice.Solutions.CheckWhetherTwoStringsAreAlmostEquivalentTest do
2+
use ExUnit.Case, async: true
3+
4+
alias LeetCodePractice.Solutions.CheckWhetherTwoStringsAreAlmostEquivalent
5+
6+
test "Case 1 works" do
7+
assert CheckWhetherTwoStringsAreAlmostEquivalent.call("aaaa", "bccb") == false
8+
end
9+
10+
test "Case 2 works" do
11+
assert CheckWhetherTwoStringsAreAlmostEquivalent.call("abcdeef", "abaaacc") == true
12+
end
13+
14+
test "Case 3 works" do
15+
assert CheckWhetherTwoStringsAreAlmostEquivalent.call("cccddabba", "babababab") == true
16+
end
17+
18+
test "Case 192 works" do
19+
assert CheckWhetherTwoStringsAreAlmostEquivalent.call("bccb", "zzzz") == false
20+
end
21+
22+
test "Non-equal length is rejected" do
23+
assert CheckWhetherTwoStringsAreAlmostEquivalent.call("aaaa", "aaaaa") == false
24+
end
25+
end

0 commit comments

Comments
 (0)