diff --git a/Hash Table/1207. Unique Number of Occurrences.py b/Hash Table/1207. Unique Number of Occurrences.py deleted file mode 100644 index dd581b0..0000000 --- a/Hash Table/1207. Unique Number of Occurrences.py +++ /dev/null @@ -1,16 +0,0 @@ -from typing import List -from collections import defaultdict - - -class Solution: - def uniqueOccurrences(self, arr: List[int]) -> bool: - count = defaultdict(int) - for val in arr: - count[val] += 1 - hash_set = set() - for key, value in count.items(): - if value not in hash_set: - hash_set.add(value) - else: - return False - return True diff --git a/README.md b/README.md index c9bd39f..f2a5572 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,11 @@ Each problem follows this structure: ## Solutions -📊 **Statistics**: 90 problems solved (migrated to new structure) +📊 **Statistics**: 91 problems solved (migrated to new structure) | Difficulty | Count | |------------|-------| -| Easy | 62 | +| Easy | 63 | | Medium | 26 | | Hard | 2 | diff --git a/docs/EASY.md b/docs/EASY.md index 1b627a3..095e82e 100644 --- a/docs/EASY.md +++ b/docs/EASY.md @@ -1,6 +1,6 @@ # Easy Problems -Total: 62 problems solved +Total: 63 problems solved ## Solutions @@ -39,6 +39,7 @@ Total: 62 problems solved | 977 | [Squares of a Sorted Array](https://leetcode.com/problems/squares-of-a-sorted-array/) | [solution.py](../problems/easy/squares_of_a_sorted_array_977/solution.py) | [test_solution.py](../problems/easy/squares_of_a_sorted_array_977/test_solution.py) | | 1119 | [Remove Vowels from a String](https://leetcode.com/problems/remove-vowels-from-a-string/) | [solution.py](../problems/easy/remove_vowels_from_a_string_1119/solution.py) | [test_solution.py](../problems/easy/remove_vowels_from_a_string_1119/test_solution.py) | | 1160 | [Find Words That Can Be Formed by Characters](https://leetcode.com/problems/find-words-that-can-be-formed-by-characters/) | [solution.py](../problems/easy/find_words_that_can_be_formed_by_characters_1160/solution.py) | [test_solution.py](../problems/easy/find_words_that_can_be_formed_by_characters_1160/test_solution.py) | +| 1207 | [Unique Number of Occurrences](https://leetcode.com/problems/unique-number-of-occurrences/) | [solution.py](../problems/easy/unique_number_of_occurrences_1207/solution.py) | [test_solution.py](../problems/easy/unique_number_of_occurrences_1207/test_solution.py) | | 1323 | [Maximum 69 Number](https://leetcode.com/problems/maximum-69-number/) | [solution.py](../problems/easy/maximum_69_number_1323/solution.py) | [test_solution.py](../problems/easy/maximum_69_number_1323/test_solution.py) | | 1365 | [How Many Numbers Are Smaller Than the Current Number](https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/) | [solution.py](../problems/easy/how_many_numbers_are_smaller_than_the_current_number_1365/solution.py) | [test_solution.py](../problems/easy/how_many_numbers_are_smaller_than_the_current_number_1365/test_solution.py) | | 1389 | [Create Target Array in the Given Order](https://leetcode.com/problems/create-target-array-in-the-given-order/) | [solution.py](../problems/easy/create_target_array_in_the_given_order_1389/solution.py) | [test_solution.py](../problems/easy/create_target_array_in_the_given_order_1389/test_solution.py) | diff --git a/problems/easy/unique_number_of_occurrences_1207/__init__.py b/problems/easy/unique_number_of_occurrences_1207/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/problems/easy/unique_number_of_occurrences_1207/solution.py b/problems/easy/unique_number_of_occurrences_1207/solution.py new file mode 100644 index 0000000..58319b9 --- /dev/null +++ b/problems/easy/unique_number_of_occurrences_1207/solution.py @@ -0,0 +1,40 @@ +# Tags: Array, Hash Table + +from collections import Counter + + +class Solution: + def unique_occurrences(self, arr: list[int]) -> bool: + """ + Check whether every distinct value in arr has a unique number of occurrences. + + Args: + arr: Input list of integers. + + Returns: + True if no two distinct values occur the same number of times, + otherwise False. + + Time complexity: O(n) + - n is the length of arr, k is the number of distinct values (k <= n) + - Counter(arr) scans the list once and each insertion/update is O(1) + on average: O(n) + - count.values() iterates over k counts: O(k) + - set(...) hashes each of the k counts: O(k) + - len(...) and the comparison are O(1) + - Total: O(n) + O(k) + O(k) = O(n), since k <= n + - Worst case: hash collisions could degrade dict/set operations, but + this is not a practical concern for small integers + - Tighter bound: the counts sum to n, so there are at most O(sqrt(n)) + distinct counts if they are all unique; this does not change the + overall O(n) cost dominated by counting + + Space complexity: O(k) + - Counter stores one entry per distinct value: O(k) + - The set of counts holds at most k values (usually far fewer): O(k) + - No recursion, so no call stack overhead + - Total auxiliary space: O(k), which is O(n) in the worst case when + all values are distinct; the output is a single bool: O(1) + """ + count = Counter(arr) + return len(set(count.values())) == len(count.keys()) diff --git a/problems/easy/unique_number_of_occurrences_1207/test_solution.py b/problems/easy/unique_number_of_occurrences_1207/test_solution.py new file mode 100644 index 0000000..27fe6b4 --- /dev/null +++ b/problems/easy/unique_number_of_occurrences_1207/test_solution.py @@ -0,0 +1,15 @@ +import pytest +from tests.base_test import BaseTestSolution +from .solution import Solution + + +class TestSolution(BaseTestSolution): + solution = Solution() + + @pytest.mark.parametrize("method_name, arr, expected, timeout", [ + ('unique_occurrences', [1, 2, 2, 1, 1, 3], True, BaseTestSolution.DEFAULT_TIMEOUT), + ('unique_occurrences', [1, 2], False, BaseTestSolution.DEFAULT_TIMEOUT), + ('unique_occurrences', [-3, 0, 1, -3, 1, 1, 1, -3, 10, 0], True, BaseTestSolution.DEFAULT_TIMEOUT), + ]) + def test_unique_occurrences(self, method_name, arr, expected, timeout): + self._run_test(self.solution, method_name, (arr,), expected, timeout)