
Problem Statement
In the given problem, you are required to handle an array of integers nums
that is sorted in a non-decreasing order. The task is to modify this array in such a way that each unique element does not appear more than twice, while maintaining the relative order of the elements. This modification should be done in-place, indicating that no additional space should be used aside from the given array.
The function should then return the size, termed as k
, of the subarray that begins from the start and contains no duplicates, where each unique element appears at most twice. You do not need to concern yourself with what lies beyond the first k
elements of the array.
It is critical to note that the solution should only use O(1) additional space, focusing on efficient handling of the memory without creating extra copies of the array.
Examples
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).
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).
Constraints
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums
is sorted in non-decreasing order.
Approach and Intuition
The approach to solving this problem hinges on the careful manipulation of array indices to ensure each unique element appears no more than twice. Here is a step-by-step breakdown:
Start by initializing a counter or index, say
k
, which will hold the position where the next element should be placed in the array. Initializek
to 0 which will be incremented as valid elements are found.Iterate through the array and compare each element to its predecessor. Keep count of how many times a current number appears consecutively.
If a number appears for the first or second time consecutively, increment the position
k
and setnums[k]
to this number, making sure not to incrementk
on finding the third consecutive appearance or more.Continue the above until the entire array has been processed.
Here are specifics from each example to clarify the process:
Example 1:
- Input:
nums = [1,1,1,2,2,3]
- As the array is iterated,
1
is allowed twice, the third1
is skipped, both2
's are allowed, and3
is allowed as it does not exceed the count of two. - Output: The modified array starts with
[1,1,2,2,3]
followed by any elements, withk=5
.
- Input:
Example 2:
- Input:
nums = [0,0,1,1,1,1,2,3,3]
- Iterate similarly, allowing at most two appearances of each number. Skip the third and fourth occurrences of
1
. - Output: The modified array starts with
[0,0,1,1,2,3,3]
, withk=7
.
- Input:
This solution leverages simple pointer manipulation and condition checks to achieve the desired state of the array, which aligns well with the constraint of constant space complexity.
Solutions
- C++
- Java
- Python
class Solution {
public:
int processDuplicates(vector<int>& elements) {
if (elements.empty()) return 0;
int read = 1; // Index for reading elements
int write = 1; // Index to write to the array
int currentCount = 1; // Current number duplicates count
while (read < elements.size()) {
if (elements[read] == elements[read - 1]) {
currentCount++;
if (currentCount > 2) {
read++;
continue;
}
} else {
currentCount = 1;
}
elements[write] = elements[read];
write++;
read++;
}
elements.resize(write);
return write;
}
};
The given C++ code provides a solution for removing excess duplicates from a sorted array, allowing a maximum of two occurrences for each element. Below is the step-by-step breakdown of how the code operates:
- Define a method
processDuplicates
that receives a reference to a vector of integers. - Check if the input vector
elements
is empty. If yes, return 0 as there are no elements to process. - Initialize two pointers:
read
starts at 1, used for reading through the vector.write
also starts at 1, used to indicate the position to write the allowed duplicates into the array.
- Set
currentCount
to 1 to track the frequency of the current element. - Begin a loop to iterate through the array starting from the second element:
- Increment the
currentCount
if the current (read
pointer) and previous element (read-1
) are the same. - If
currentCount
exceeds 2, skip the current element by incrementing theread
pointer and continue to next iteration. - If a new element is encountered (or
currentCount
is acceptable), resetcurrentCount
to 1, and copy the element at theread
pointer to the position indicated by thewrite
pointer. - Increment both
write
andread
pointers.
- Increment the
- After the loop, reduce the size of the input vector to the value of
write
pointer which indicates the number of elements in the modified array. - Return the length of the modified array from the method.
This solution efficiently maintains two pointers and controls the number of allowed duplicates in a single linear pass, ensuring that space complexity is minimized, with changes made in-place.
class Solution {
public int eliminateDuplicates(int[] elements) {
if (elements.length == 0) {
return 0;
}
int read = 1;
int write = 1;
int frequency = 1;
while (read < elements.length) {
if (elements[read] == elements[read - 1]) {
frequency++;
if (frequency > 2) {
read++;
continue;
}
} else {
frequency = 1;
}
elements[write] = elements[read];
write++;
read++;
}
return write;
}
}
The Java program presented tackles the problem of removing excess duplicates from a sorted array, where each element can appear at most twice. Follow these straightforward steps in the code to understand the functionality:
- Check if array is empty, if so, return 0.
- Initialize two pointers,
read
andwrite
, both set to the index 1, andfrequency
to count the occurrences of each element, starting at 1. - Use a loop to iterate through the array:
- Compare the current element with the previous one.
- If they are the same, increment the
frequency
. - If
frequency
is greater than 2, just move theread
pointer forward and continue to next iteration. - If a new element is found or the frequency of the current element is less than or equal to 2, reset
frequency
to 1, and write the value ofread
pointer's element to thewrite
pointer's position. - Move both pointers forward.
- After completing loop,
write
pointer represents the length of the modified array without excess duplicates. - Return the new length of the array as indicated by the
write
pointer.
This method efficiently adjusts the array in-place to ensure no element occurs more than twice, while only utilizing a single pass through the array and O(1) extra space for the frequency and pointer variables.
class Solution:
def remove_extra_duplicates(self, numbers: List[int]) -> int:
if not numbers:
return 0
current = 1
insertPosition = 1
occurrences = 1
while current < len(numbers):
if numbers[current] == numbers[current - 1]:
occurrences += 1
if occurrences > 2:
current += 1
continue
else:
occurrences = 1
numbers[insertPosition] = numbers[current]
insertPosition += 1
current += 1
del numbers[insertPosition:]
return len(numbers)
This solution defines a Python class Solution
which includes a method remove_extra_duplicates
to tackle the issue of removing extraneous duplicates from a sorted array, allowing at most two occurrences of each number. The method works as follows:
- Initialize
insertPosition
andcurrent
pointers to the index 1, andoccurrences
to 1 to track the number of occurrences of the current number. - Iterate over the list of numbers using the
current
pointer:- If the current number equals the previous number, increment the
occurrences
counter. - If
occurrences
exceeds 2, skip the current element by simply incrementing thecurrent
pointer without updating theinsertPosition
. - If the current number does not equal the previous one, reset the
occurrences
to 1. - Assign the current number to the position indicated by
insertPosition
and increment bothinsertPosition
andcurrent
.
- If the current number equals the previous number, increment the
- After completing the iterations, the numbers after the
insertPosition
index are redundant and are removed usingdel numbers[insertPosition:]
. - Finally, return the modified length of the array using
len(numbers)
, which represents the length of the array with at most two occurrences of each number.
This method ensures that the array retains up to two duplicates of each element while maintaining sorted order without requiring additional space for the result, as the modifications are done in-place.
No comments yet.