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.
Example 1:
Input: nums = [1,1,1,2,2,3]
Output: 5, nums = [1,1,2,2,3,_]
Example 2:
Input: nums = [0,0,1,1,1,1,2,3,3]
Output: 7, nums = [0,0,1,1,2,3,3,_,_]
Constraints:
1 <= nums.length <= 3 * 10^4
-10^4 <= nums[i] <= 10^4
nums
is sorted in non-decreasing order.A brute force approach would involve creating a new array, iterating through the original array, and adding elements to the new array only if they appear less than or equal to twice. This approach is straightforward to understand but requires extra space.
def remove_duplicates_naive(nums):
new_nums = []
counts = {}
for num in nums:
if num not in counts:
counts[num] = 0
counts[num] += 1
if counts[num] <= 2:
new_nums.append(num)
nums[:] = new_nums # Modify nums in-place
return len(nums)
new_nums
that, in the worst case, could store all elements of the original array.The optimal solution uses a two-pointer approach to modify the array in-place. We maintain a slow pointer (k
) that points to the next available position in the modified array and a fast pointer (i
) that iterates through the original array. We copy the element at nums[i]
to nums[k]
only if the element appears less than twice in the modified part of the array.
def remove_duplicates(nums):
k = 0 # Index for the modified array
for i in range(len(nums)):
if k < 2 or nums[i] != nums[k - 2]:
nums[k] = nums[i]
k += 1
return k
k = 0
. The k
pointer indicates the index up to which the array has been modified and contains the desired elements.i
.k < 2 or nums[i] != nums[k - 2]
checks whether we can add nums[i]
to the modified array.
k < 2
, it means we have less than two elements in the modified array, so we can safely add the current element.nums[i] != nums[k - 2]
, it means the current element is different from the element two positions before k
, so it won't violate the at-most-twice rule.nums[i]
to nums[k]
and increment k
.k
, which represents the length of the modified array.