Skip to content

Commit

Permalink
Merge pull request #80 from BrianLusina/feat/remove-duplicates
Browse files Browse the repository at this point in the history
Algorithms | Remove duplicates from array
  • Loading branch information
BrianLusina authored Jan 17, 2024
2 parents 2a093aa + 72b6364 commit 11eb19e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 15 deletions.
4 changes: 3 additions & 1 deletion DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@
* [Test Daily Temperatures](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/stack/daily_temperatures/test_daily_temperatures.py)
* Taxi Numbers
* [Taxi Numbers](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/taxi_numbers/taxi_numbers.py)
* Two Pointers
* Merge Sorted Arrays
* [Test Merge Sorted Arrays](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/two_pointers/merge_sorted_arrays/test_merge_sorted_arrays.py)
* Unique Bsts
* [Unique Bsts](https://github.com/BrianLusina/PythonSnips/blob/master/algorithms/unique_bsts/unique_bsts.py)

Expand Down Expand Up @@ -694,7 +697,6 @@
* [Test Lonely Integer](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_lonely_integer.py)
* [Test Longest Consecutive Sequence](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_longest_consecutive_sequence.py)
* [Test Max Subarray](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_max_subarray.py)
* [Test Merge Sorted Arrays](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_merge_sorted_arrays.py)
* [Test Sub Array With Sum](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_sub_array_with_sum.py)
* [Test Three Sum](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_three_sum.py)
* [Test Zig Zag Sequence](https://github.com/BrianLusina/PythonSnips/blob/master/tests/datastructures/arrays/test_zig_zag_sequence.py)
Expand Down
39 changes: 39 additions & 0 deletions algorithms/arrays/remove_duplicates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,42 @@ and 4 respectively. It doesn't matter what values are set beyond the returned le
Constraints:

0 <= nums.length <= 3 * 104 -104 <= nums[i] <= 104 nums is sorted in ascending order.

---

## Remove Duplicates from Sorted Array II

Given an integer array nums sorted in non-decreasing order, remove some duplicates in-place such that each unique
element appears at most twice. The relative order of the elements should be kept the same.

Since it is impossible to change the length of the array in some languages, you must instead have the result be placed
in the first part of the array nums. More formally, if there are k elements after removing the duplicates, then the
first k elements of nums should hold the final result. It does not matter what you leave beyond the first k elements.

Return k after placing the final result in the first k slots of nums.

Do not allocate extra space for another array. You must do this by modifying the input array in-place with O(1) extra
memory.

```text
Example 1:
Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
Explanation: Your function should return k = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
```

```text
Example 2:
Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3,_,_]
Explanation: Your function should return k = 7, with the first seven elements of nums being 0, 0, 1, 1, 2, 3 and 3 respectively.
It does not matter what you leave beyond the returned k (hence they are underscores).
```

### Related Topics

- Array
- Two Pointers
42 changes: 29 additions & 13 deletions algorithms/arrays/remove_duplicates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ def remove_duplicates_from_sorted_list(nums: List[int]) -> int:
modifies the list in place so no extra space is used, effectively the Space complexity is O(1). However, the time
complexity is O(n) where n is the length of the list.
This uses 2 pointers to keep track of the unique and non-unique elements in the list of integers. i pointer is at
the element before and j pointer is at the next element. These are moved along the elements in the list as below:
1. as long as j is less than the length of the list we shall iterate until j reaches the end of the list, i.e. the
This uses 2 pointers to keep track of the unique and non-unique elements in the list of integers. 'i' pointer is at
the element before, and j pointer is at the next element. These are moved along the elements in the list as below:
1. As long as j is less than the length of the list, we shall iterate until j reaches the end of the list, i.e. the
last element in the list
2. if the element at position i is not equal to the element at position j(at this point j is ahead of i), we
increase the i index by 1 and assign the index at i the value of the index at j and increment the index at j, i.e.
moving the pointer j and i forward by 1
3. if the elements are equal, then that means we have encountered a duplicate & therefore we move the pointer j
2. if the element at position i is not equal to the element at position j(at this point j is ahead of i), we
increase the i index by 1 and assign the index at 'i' the value of the index at j and increment the index at j,
i.e. moving the pointer j and i forward by 1
3. If the elements are equal, then that means we have encountered a duplicate & therefore we move the pointer j
forward by 1 until we encounter a unique element.
4. When the loop is complete we return i +1. This is because the pointer i is now pointing to the last unique
4. When the loop is complete, we return i +1. This is because the pointer 'i' is now pointing to the last unique
element in the list.
The other elements after the pointer i are the duplicate elements. This modifies the sorted list in place retaining
"some" of the duplicated elements to the right of i. Note that this means we will not know how many times an
element occurred in the original sorted list of elements.
The other elements after the pointer 'i' are the duplicate elements. This modifies the sorted list in place
retaining "some" of the duplicated elements to the right of i. Note that this means we will not know how many times
an element occurred in the original sorted list of elements.
@param nums: list of integers
@return: integer denoting the number of unique elements in the list
Args:
nums (list): list of integers.
Returns:
int: integer denoting the number of unique elements in the list
"""

if not nums:
Expand All @@ -44,3 +46,17 @@ def remove_duplicates_from_sorted_list(nums: List[int]) -> int:
nums[i] = nums[j]
j += 1
return i + 1


def remove_duplicates_two(nums: List[int]) -> int:
# Initialize an integer k that updates the kth index of the array...
# only when the current element does not match either of the two previous indexes. ...
k = 0
# Traverse all elements through loop...
for num in nums:
# If the index does not match elements, count that element and update it...
if k < 2 or num != nums[k - 2]:
nums[k] = num
k += 1
# Return k after placing the final result in the first k slots of nums...
return k
20 changes: 19 additions & 1 deletion algorithms/arrays/remove_duplicates/test_remove_duplicates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest

from . import remove_duplicates_from_sorted_list
from . import remove_duplicates_from_sorted_list, remove_duplicates_two


class RemoveDuplicateTestCase(unittest.TestCase):
Expand Down Expand Up @@ -33,5 +33,23 @@ def test_3(self):
self.assertEqual(expected, actual)


class RemoveDuplicatesTwoTestCase(unittest.TestCase):
def test_1(self):
"""nums = [1,1,1,2,2,3] should return 5"""
nums = [1, 1, 1, 2, 2, 3]
expected = 5
actual = remove_duplicates_two(nums)

self.assertEqual(expected, actual)

def test_2(self):
"""nums = [0,0,1,1,1,1,2,3,3] should return 7"""
nums = [0, 0, 1, 1, 1, 1, 2, 3, 3]
expected = 7
actual = remove_duplicates_two(nums)

self.assertEqual(expected, actual)


if __name__ == '__main__':
unittest.main()

0 comments on commit 11eb19e

Please sign in to comment.