Skip to content

Commit 6da8745

Browse files
authored
Merge pull request #114 from BrianLusina/feat/contains-duplicates
feat(data structures, arrays): contains duplicates
2 parents 5493cec + 946769d commit 6da8745

17 files changed

+154
-37
lines changed

DIRECTORY.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@
8080
* Graphs
8181
* Course Schedule
8282
* [Test Course Schedule](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/graphs/course_schedule/test_course_schedule.py)
83+
* Frog Position After T Seconds
84+
* [Test Frog Position After T Seconds](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/graphs/frog_position_after_t_seconds/test_frog_position_after_t_seconds.py)
8385
* Greedy
8486
* Min Arrows
8587
* [Test Find Min Arrows](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/greedy/min_arrows/test_find_min_arrows.py)
@@ -192,6 +194,9 @@
192194
* [Test Array Advance Game](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/array_advance_game/test_array_advance_game.py)
193195
* Array Diff
194196
* [Diff Elements In List](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/array_diff/diff_elements_in_list.py)
197+
* Contains Duplicates
198+
* [Test Contains Nearby Almost Duplicate](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/contains_duplicates/test_contains_nearby_almost_duplicate.py)
199+
* [Test Contains Nearby Duplicate](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/contains_duplicates/test_contains_nearby_duplicate.py)
195200
* Distinct
196201
* [Distinct Values](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/arrays/distinct/distinct_values.py)
197202
* Matrix
@@ -288,8 +293,10 @@
288293
* [Test Binary Search Tree Search](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/search_tree/test_binary_search_tree_search.py)
289294
* [Test Utils](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/test_utils.py)
290295
* Tree
296+
* [Binary Tree](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/binary_tree.py)
291297
* [Test Binary Tree](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/test_binary_tree.py)
292298
* [Test Binary Tree Deserialize](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/test_binary_tree_deserialize.py)
299+
* [Test Binary Tree Min Camera Cover](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/test_binary_tree_min_camera_cover.py)
293300
* [Test Binary Tree Serialize](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/test_binary_tree_serialize.py)
294301
* [Test Binary Tree Visible Nodes](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/tree/test_binary_tree_visible_nodes.py)
295302
* [Utils](https://github.com/BrianLusina/PythonSnips/blob/master/datastructures/trees/binary/utils.py)
@@ -857,8 +864,6 @@
857864
* [Test Array Pair Sum](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_array_pair_sum.py)
858865
* [Test Build Tower](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_build_tower.py)
859866
* [Test Cascading Subsets](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_cascading_subsets.py)
860-
* [Test Contains Nearby Almost Duplicate](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_contains_nearby_almost_duplicate.py)
861-
* [Test Contains Nearby Duplicate](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_contains_nearby_duplicate.py)
862867
* [Test Dynamic Array](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_dynamic_array.py)
863868
* [Test Find Unique](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_find_unique.py)
864869
* [Test Highest Rank](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_highest_rank.py)

datastructures/arrays/contains_duplicates/README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,18 @@ Example 3:
1717
Input: nums = [1,1,1,3,3,4,3,2,4,2]
1818
Output: true
1919

20+
---
21+
2022
## Contains Duplicates II
2123

22-
Given an integer array nums and an integer k, return true if there are two distinct indices i and j in the array such that nums[i] == nums[j] and abs(i - j) <= k.
24+
Given an integer array nums and an integer k, return true if there are two distinct indices i and j in the array such
25+
that nums[i] == nums[j] and abs(i - j) <= k.
26+
27+
Constraints:
28+
29+
- 1 <= nums.length <= 10^3
30+
- -10^3 <= nums[i] <= 10^3
31+
- 0 <= k <= 10^4
2332

2433
Example 1:
2534

@@ -34,6 +43,53 @@ Example 3:
3443
Input: nums = [1,2,3,1,2,3], k = 2
3544
Output: false
3645

46+
### Solution
47+
48+
The core intuition of solving this problem is maintaining a sliding window of size k to track elements within a limited
49+
range using a set. As we iterate through the array, we check if the current element already exists in the set,
50+
indicating a duplicate within the range. If it exists, we return TRUE. Otherwise, the element is added to the set.
51+
If the set size exceeds k, we remove the oldest element to ensure that the set only contains elements within the valid
52+
range at any time.
53+
54+
Using the above intuition, the solution can be implemented as follows:
55+
56+
1. Create a set, `seen`, to track elements within the sliding window of size `k`.
57+
2. Loop through each index `i` of the array `nums`.
58+
- If the current element, `nums[i]`, already exists in the set, a duplicate exists within a range of `k` indices.
59+
Therefore, we return TRUE.
60+
- Add the current element to the set.
61+
- If the set’s size exceeds `k`, remove the oldest element in the window (`nums[i - k]`) to maintain the window’s size.
62+
This ensures only elements within the range k are tracked.
63+
64+
3. If the loop completes without finding duplicates, we return FALSE.
65+
66+
Let’s look at the following illustration to get a better understanding of the solution:
67+
68+
![Solution 1](./images/solutions/contains_duplicates_ii_solution_1.png)
69+
![Solution 2](./images/solutions/contains_duplicates_ii_solution_2.png)
70+
![Solution 3](./images/solutions/contains_duplicates_ii_solution_3.png)
71+
![Solution 4](./images/solutions/contains_duplicates_ii_solution_4.png)
72+
![Solution 5](./images/solutions/contains_duplicates_ii_solution_5.png)
73+
![Solution 6](./images/solutions/contains_duplicates_ii_solution_6.png)
74+
![Solution 7](./images/solutions/contains_duplicates_ii_solution_7.png)
75+
![Solution 8](./images/solutions/contains_duplicates_ii_solution_8.png)
76+
![Solution 9](./images/solutions/contains_duplicates_ii_solution_9.png)
77+
![Solution 10](./images/solutions/contains_duplicates_ii_solution_10.png)
78+
![Solution 11](./images/solutions/contains_duplicates_ii_solution_11.png)
79+
80+
#### Time Complexity
81+
82+
The time complexity of the solution is O(n), where n is the length of the input array `nums`.
83+
This is because we iterate through the array once, performing constant-time operations for each element.
84+
85+
#### Space Complexity
86+
87+
The space complexity of the solution is O(min(n, k)), where n is the length of the input array `nums` and k is the
88+
maximum number of steps between duplicate elements. This is because we use a set to store the elements within the
89+
sliding window of size `k`, and the maximum size of the set is limited by the minimum of `n` and `k`.
90+
91+
---
92+
3793
## Contains Duplicate III
3894

3995
Given an integer array nums and two integers k and t, return true if there are two distinct indices i and j in the array

datastructures/arrays/contains_duplicates/__init__.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,60 @@
11
import sys
2-
from typing import List
2+
from typing import List, Set
33

44

55
def contains_nearby_duplicate(nums: List[int], k: int) -> bool:
6+
"""
7+
Checks if there are any duplicate elements within k steps of each other
8+
in the given list of numbers.
9+
10+
Args:
11+
nums (List[int]): The list of numbers to check.
12+
k (int): The maximum number of steps between duplicate elements.
13+
14+
Returns:
15+
bool: True if there are any duplicate elements within k steps of each other, False otherwise.
16+
"""
17+
# Dictionary to store the indices of the numbers we have seen so far
618
d = dict()
719
for i, n in enumerate(nums):
20+
# If we have seen this number before and it is within k steps of the current position
821
if n in d and i - d[n] <= k:
922
return True
23+
# Store the index of the current number
1024
d[n] = i
25+
# If we have not found any duplicate elements within k steps of each other
26+
return False
27+
28+
29+
def contains_nearby_duplicates_2(nums: List[int], k: int) -> bool:
30+
"""
31+
Checks if there are any duplicate elements within k steps of each other
32+
in the given list of numbers.
33+
34+
Args:
35+
nums (List[int]): The list of numbers to check.
36+
k (int): The maximum number of steps between duplicate elements.
37+
38+
Returns:
39+
bool: True if there are any duplicate elements within k steps of each other, False otherwise.
40+
"""
41+
# Set to store the numbers we have seen so far
42+
seen: Set[int] = set()
43+
# Iterate over the list of numbers
44+
for idx in range(len(nums)):
45+
# If we have seen this number before
46+
if nums[idx] in seen:
47+
# Return True
48+
return True
49+
# Add the current number to the set of seen numbers
50+
seen.add(nums[idx])
51+
52+
# If we have seen more than k numbers
53+
if len(seen) > k:
54+
# Remove the number that is k steps behind the current number
55+
seen.remove(nums[idx - k])
56+
57+
# If we have not found any duplicate elements within k steps of each other
1158
return False
1259

1360

28.6 KB
Loading
28.2 KB
Loading
28.8 KB
Loading
21 KB
Loading
19.8 KB
Loading
21 KB
Loading
19.5 KB
Loading

0 commit comments

Comments
 (0)