Given an integer array nums
and an integer val
, remove all occurrences of val
in nums
in-place. The order of the elements may be changed. Then return the number of elements in nums
which are not equal to val
.
Consider the number of elements in nums
which are not equal to val
be k
, to get accepted, you need to do the following things:
nums
such that the first k
elements of nums
contain the elements which are not equal to val
. The remaining elements of nums
are not important as well as the size of nums
.k
.Example 1:
Input: nums = [3,2,2,3], val = 3
Output: 2, nums = [2,2,_,_]
Explanation: Your function should return k = 2, with the first two elements of nums being 2.
It does not matter what you leave beyond the returned k (hence they are underscores).
Example 2:
Input: nums = [0,1,2,2,3,0,4,2], val = 2
Output: 5, nums = [0,1,4,0,3,_,_,_]
Explanation: Your function should return k = 5, with the first five elements of nums containing 0, 0, 1, 3, and 4.
Note that the five elements can be returned in any order.
It does not matter what you leave beyond the returned k (hence they are underscores).
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for removing a specific item from a collection of items involves checking each item individually. When we find the item to remove, we figure out a way to get rid of it and then continue looking for other occurrences.
Here's how the algorithm would work step-by-step:
def remove_element_brute_force(numbers, value_to_remove):
index = 0
while index < len(numbers):
# Check if the current element should be removed
if numbers[index] == value_to_remove:
# Remove the element by shifting elements to the left
for sub_index in range(index, len(numbers) - 1):
numbers[sub_index] = numbers[sub_index + 1]
numbers.pop()
# Do not increment index after removal; check current index again
else:
# Move to the next element in the list
index += 1
return len(numbers)
The most efficient way to remove specific items from a collection involves strategically shifting elements. Instead of creating a new collection or repeatedly resizing the original, we overwrite unwanted values with those we want to keep, essentially compressing the collection in place.
Here's how the algorithm would work step-by-step:
def remove_element(numbers, value_to_remove):
index_to_fill = 0
for i in range(len(numbers)):
if numbers[i] != value_to_remove:
# Overwrite the element at index_to_fill with the current element.
numbers[index_to_fill] = numbers[i]
index_to_fill += 1
# The new length is the number of elements that were kept.
return index_to_fill
Case | How to Handle |
---|---|
Empty input array (nums is null or has zero length) | Return 0 since there are no elements to process. |
All elements in the array are equal to val | The function should return 0 and the array should effectively be empty (first 0 elements are the result). |
No elements in the array are equal to val | The function should return the original length of the array, and the array should remain unchanged. |
Array contains a single element which is equal to val | The function should return 0 and the first element is what is left in the array up to position 0. |
Array contains a single element which is not equal to val | The function should return 1 and the array remains as is. |
Array contains many occurrences of val scattered throughout | The two-pointer approach correctly compacts the array, moving non-val elements to the beginning. |
Large input array (e.g., exceeding available memory) | The in-place nature of the algorithm avoids excessive memory usage and scales efficiently. |
Array contains negative numbers, zeros, and positive numbers, all mixed with val | The algorithm should treat each element the same regardless of its value (positive, negative, or zero). |