Given an array of integers nums
containing n + 1
integers where each integer is in the range [1, n]
inclusive.
There is only one repeated number in nums
, return this repeated number.
You must solve the problem without modifying the array nums
and using only constant extra space.
Example 1:
Input: nums = [1,3,4,2,2] Output: 2
Example 2:
Input: nums = [3,1,3,4,2] Output: 3
Example 3:
Input: nums = [3,3,3,3,3] Output: 3
Constraints:
1 <= n <= 105
nums.length == n + 1
1 <= nums[i] <= n
nums
appear only once except for precisely one integer which appears two or more times.Follow up:
nums
?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 approach to finding a duplicate in a list of numbers is like manually comparing each number to every other number in the list. We systematically check all possible pairs until we find a match, meaning a number appears more than once.
Here's how the algorithm would work step-by-step:
def find_duplicate_number_brute_force(numbers):
list_length = len(numbers)
for first_index in range(list_length):
# Compare current number to the rest of the list
for second_index in range(first_index + 1, list_length):
# If a duplicate is found, we return it
if numbers[first_index] == numbers[second_index]:
return numbers[first_index]
# Return -1 if no duplicate is found
return -1
The best way to find the duplicate number is by cleverly using the properties of the numbers themselves. We'll treat the problem like finding a loop in a linked list, where each number points to another number.
Here's how the algorithm would work step-by-step:
def find_duplicate_number(numbers):
slow_pointer = numbers[0]
fast_pointer = numbers[0]
while True:
slow_pointer = numbers[slow_pointer]
fast_pointer = numbers[numbers[fast_pointer]]
# Detect the intersection point of the two pointers
if slow_pointer == fast_pointer:
break
pointer_to_beginning = numbers[0]
# One pointer goes back to the beginning
while pointer_to_beginning != slow_pointer:
slow_pointer = numbers[slow_pointer]
pointer_to_beginning = numbers[pointer_to_beginning]
# The meeting point is the duplicate number
return slow_pointer
Case | How to Handle |
---|---|
Null or empty input array | Throw an IllegalArgumentException or return -1 to indicate invalid input. |
Array with only two elements, where one is the duplicate | The algorithm should correctly identify the duplicate in a size 2 array. |
Array where the duplicate is the first element | The algorithm should correctly identify the duplicate even when it's at the beginning. |
Array where the duplicate is the last element | The algorithm should correctly identify the duplicate even when it's at the end. |
Large input array (close to memory limit) | Consider using a space-efficient algorithm like the Floyd's Tortoise and Hare (cycle detection) method to avoid memory issues. |
Array with all elements being the same (all are duplicates) | The algorithm should correctly identify the single duplicate number in this scenario. |
Array contains numbers outside the range [1, n] | Throw an IllegalArgumentException or return -1 to indicate invalid input, as the problem statement defines the range. |
Array where n is very large, potentially leading to integer overflow in calculations | Choose appropriate data types (e.g., long) or algorithm to avoid integer overflow. |