Given a fixed-length integer array arr
, duplicate each occurrence of zero, shifting the remaining elements to the right.
Note that elements beyond the length of the original array are not written. Do the above modifications to the input array in place and do not return anything.
Example 1:
Input: arr = [1,0,2,3,0,4,5,0] Output: [1,0,0,2,3,0,0,4] Explanation: After calling your function, the input array is modified to: [1,0,0,2,3,0,0,4]
Example 2:
Input: arr = [1,2,3] Output: [1,2,3] Explanation: After calling your function, the input array is modified to: [1,2,3]
Constraints:
1 <= arr.length <= 104
0 <= arr[i] <= 9
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 directly simulates the duplication process. We go through the numbers one by one, and when we see a zero, we insert another zero right after it, shifting everything else down.
Here's how the algorithm would work step-by-step:
def duplicate_zeros(numbers):
index = 0
while index < len(numbers):
# Found a zero, need to insert another
if numbers[index] == 0:
# Shift elements to the right to make space
for element_index in range(len(numbers) - 1, index, -1):
numbers[element_index] = numbers[element_index - 1]
# Protect against array overflow and duplicate the zero.
if index + 1 < len(numbers):
numbers[index + 1] = 0
# Move past the duplicated zero.
index += 2
# Keep traversing to find the next zero.
else:
index += 1
The most efficient way to handle this problem involves working backward to avoid constantly shifting elements. First, we determine the final size of the modified list, and then we fill it from the end toward the start.
Here's how the algorithm would work step-by-step:
def duplicate_zeros(array):
number_of_zeros = array.count(0)
expanded_array_length = len(array) + number_of_zeros
last_element_index = len(array) - 1
expanded_array_last_index = expanded_array_length - 1
# Iterate from the end of the original array to the beginning
while last_element_index >= 0:
if expanded_array_last_index > last_element_index:
# Copy non-zero elements to the end of the expanded array
if array[last_element_index] != 0:
if expanded_array_last_index < len(array):
array[expanded_array_last_index] = array[last_element_index]
expanded_array_last_index -= 1
# Duplicate zeros, adjusting array indices as needed
else:
if expanded_array_last_index < len(array):
array[expanded_array_last_index] = 0
expanded_array_last_index -= 1
if expanded_array_last_index < len(array):
array[expanded_array_last_index] = 0
expanded_array_last_index -= 1
else:
# When expanded_array_last_index == last_element_index, early termination
break
last_element_index -= 1
Case | How to Handle |
---|---|
Null or empty array input | Return immediately or throw an IllegalArgumentException, depending on requirements. |
Array with only one element | The algorithm should handle this as there are no duplicates to process and the array remains unchanged. |
Array with all zeros | The algorithm should correctly expand the array, effectively doubling the number of zeros. |
Array with no zeros | The algorithm should complete without modification as there's nothing to duplicate. |
Array filled with zeros, nearing maximum size allowed | Ensure the algorithm does not exceed memory constraints when expanding the array, causing an out-of-memory error. |
Array with zeros at the end | The insertion logic must handle overwriting existing trailing elements correctly. |
Integer overflow when calculating array indices or resizing | Use appropriate data types (e.g., long) for calculations to avoid integer overflow errors during array manipulation. |
Very large array size close to allowed maximum | Verify that algorithm runtime is acceptable for the large input array, especially if using shifting operations. |