Given an integer array nums
of length n
where all the integers of nums
are in the range [1, n]
and each integer appears at most twice, return an array of all the integers that appears twice.
You must write an algorithm that runs in O(n)
time and uses only constant auxiliary space, excluding the space needed to store the output
Example 1:
Input: nums = [4,3,2,7,8,2,3,1] Output: [2,3]
Example 2:
Input: nums = [1,1,2] Output: [1]
Example 3:
Input: nums = [1] Output: []
Constraints:
n == nums.length
1 <= n <= 105
1 <= nums[i] <= n
nums
appears once or twice.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 to find duplicates in a collection of numbers is like comparing each number with every other number. We go through the numbers one by one and, for each, check if it appears anywhere else in the collection.
Here's how the algorithm would work step-by-step:
def find_all_duplicates_brute_force(numbers):
duplicate_numbers = []
number_of_elements = len(numbers)
for first_index in range(number_of_elements):
first_number = numbers[first_index]
# Compare the current number with the rest
for second_index in range(number_of_elements):
# Avoid comparing the number to itself
if first_index != second_index:
second_number = numbers[second_index]
# Mark as duplicate if a match is found
if first_number == second_number:
# Ensures no redundant addition of same element
if first_number not in duplicate_numbers:
duplicate_numbers.append(first_number)
return duplicate_numbers
The efficient way to find duplicates takes advantage of the array's structure itself to track what's been seen. We cleverly use the numbers in the array as pointers to spots within the same array. By modifying the array based on what we find, we can easily identify repeats.
Here's how the algorithm would work step-by-step:
def find_duplicates(nums):
duplicate_numbers = []
for index in range(len(nums)):
current_number = abs(nums[index])
corresponding_index = current_number - 1
# Use array indices as a hash key.
if nums[corresponding_index] < 0:
duplicate_numbers.append(current_number)
# Mark each number as seen by negating value at index.
else:
nums[corresponding_index] *= -1
# Restore the array to its original state.
for index in range(len(nums)):
nums[index] = abs(nums[index])
return duplicate_numbers
Case | How to Handle |
---|---|
Null input array | Check for null input and return an empty list to avoid NullPointerException. |
Empty array | Return an empty list immediately as there are no duplicates. |
Array with only one element | Return an empty list because a single element cannot be a duplicate. |
Array with all elements being the same | The in-place modification approach correctly identifies the repeating element. |
Array with no duplicates | Return an empty list as specified in problem description |
Maximum sized input array close to integer limits (n elements) | Ensure algorithm has O(n) time complexity and reasonable space complexity (ideally O(1) or O(log n)) to avoid resource exhaustion. |
Array contains values outside the range [1, n] | Handle invalid input, by either ignoring, throwing an exception or filtering the array, depending on the requirements. |
Integer overflow during calculations (if using arithmetic tricks) | Use appropriate data types (e.g., long) or bit manipulation to prevent integer overflows during calculations if applicable. |