Remove Duplicates from Sorted Array
Given an integer array nums sorted in non-decreasing order, remove the duplicates in place so that each unique element appears only once. The relative order of the elements should be kept the same. Return k, the number of unique elements, after placing the final result in the first k slots of nums. Use a slow pointer that marks the next write position and a fast pointer that scans ahead looking for a new value.
Constraints
- 1 ≤ nums.length ≤ 3 × 104
- -100 ≤ numsi ≤ 100
- nums is sorted in non-decreasing order
Example
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4]5, nums = [0, 1, 2, 3, 4, ...]Explanation The function returns k = 5, and the first five elements of nums become [0, 1, 2, 3, 4].
In plain terms
- In place
- Making the change directly inside the given array instead of building a new one, using little to no extra memory.
- Non-decreasing order
- Each value is greater than or equal to the one before it, so repeats are allowed — for example, [1, 2, 2, 5] is in non-decreasing order.
Slow pointer writes, fast pointer scans
slow=0 (0), fast=1 (0). Same value — fast keeps scanning.
What happens in this step
slow = 0 (value 0), fast = 1 (value 0) nums[fast] == nums[slow] — same value, not new fast advances without writing since this is a duplicate of nums[slow].
Steps to visualize
- Start slow at index 0 and fast at index 1.
- Advance fast through the array looking for a value different from numsslow.
- When a new value is found, move slow forward one step and copy that value there.
- Keep scanning with fast until the array ends.
- The final value of slow + 1 is the count of unique elements.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
slow=0 (0), fast=1 (0). Same value — fast keeps scanning.
What happens in this step
slow = 0 (value 0), fast = 1 (value 0) nums[fast] == nums[slow] — same value, not new fast advances without writing since this is a duplicate of nums[slow].
Solution
function removeDuplicates(nums) {
let slow = 0;
for (let fast = 1; fast < nums.length; fast++) {
if (nums[fast] !== nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
const newLength = slow + 1;
return nums.slice(0, newLength);
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4] | [0, 1, 2, 3, 4] | example from the docstring |
nums = [1, 1, 1, 1] | [1] | every element is the same value |
nums = [1, 2, 3, 4] | [1, 2, 3, 4] | already unique, no duplicates to remove |
nums = [5] | [5] | smallest valid input, a single element |
nums = [-3, -3, -1, 0, 0, 2] | [-3, -1, 0, 2] | negative values mixed with duplicates |
nums = [1, 2, 3, 3, 3] | [1, 2, 3] | duplicates clustered at the end of the array |