26. Remove Duplicates From Sorted Array - Explanation
Description
You are given an integer array nums sorted in non-decreasing order. Your task is to remove duplicates from nums in-place so that each element appears only once.
After removing the duplicates, return the number of unique elements, denoted as k, such that the first k elements of nums contain the unique elements.
Note:
- The order of the unique elements should remain the same as in the original array.
- It is not necessary to consider elements beyond the first
kpositions of the array. - To be accepted, the first
kelements ofnumsmust contain all the unique elements.
Return k as the final result.
Example 1:
Input: nums = [1,1,2,3,4]
Output: [1,2,3,4]Explanation: You should return k = 4 as we have four unique elements.
Example 2:
Input: nums = [2,10,10,30,30,30]
Output: [2,10,30]Explanation: You should return k = 3 as we have three unique elements.
Constraints:
1 <= nums.length <= 30,000-100 <= nums[i] <= 100numsis sorted in non-decreasing order.
Topics
Prerequisites
Before attempting this problem, you should be comfortable with:
- Two Pointers - Using a read pointer and write pointer to modify arrays in-place
- In-Place Array Modification - Overwriting elements without using extra space
- Sorted Array Properties - Understanding that duplicates are always adjacent in sorted arrays
1. Sorted Set
Intuition
A set automatically removes duplicates, and a sorted set maintains order. We insert all elements into a sorted set, then copy the unique elements back to the original array. This approach is simple but uses extra space and doesn't take advantage of the array already being sorted.
Algorithm
- Insert all elements from the array into a sorted set to eliminate duplicates.
- Copy the unique elements from the set back into the beginning of the original array.
- Return the size of the set (number of unique elements).
Note: This approach is simple but uses extra O(n) space.
Time & Space Complexity
- Time complexity:
- Space complexity:
2. Two Pointers - I
Intuition
Since the array is sorted, duplicates are adjacent. We use two pointers: one (l) marks where to place the next unique element, and another (r) scans through the array. When r finds a new value (different from what's at l), we copy it to position l and advance both pointers. This modifies the array in-place.
Algorithm
- Initialize both pointers
landrto0. - Copy the current element at
rto positionl. - Skip all duplicates by advancing
rwhile consecutive elements are equal. - Move
lforward to prepare for the next unique element. - Return
las the count of unique elements.
Time & Space Complexity
- Time complexity:
- Space complexity:
3. Two Pointers - II
Intuition
A more elegant approach: we compare each element with its predecessor. Since duplicates are consecutive in a sorted array, an element is unique if it differs from the one before it. We maintain a write pointer that only advances when we find a new unique value.
Algorithm
- Start with
l = 1since the first element is always unique. - Iterate
rfrom1to the end of the array. - If
nums[r]differs fromnums[r - 1], it's a new unique value. - Copy it to position
land incrementl. - Return
las the count of unique elements.
Time & Space Complexity
- Time complexity:
- Space complexity:
Common Pitfalls
Not Leveraging the Sorted Property
The array is already sorted, meaning duplicates are always adjacent. Some solutions use a hash set or sort the array again, which wastes time and space. Since duplicates are consecutive, you only need to compare each element with its predecessor (or the last written element) to detect duplicates in O(1) space.
Returning the Wrong Value
The function should return the count of unique elements, not modify and return the array itself. Additionally, the returned length k means the first k elements of nums contain the unique values. Some solutions off-by-one error by returning l - 1 instead of l, or forget that the write pointer already represents the count of unique elements written.
Sign in to join the discussion