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 <= 1040 <= arr[i] <= 9When 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 core idea is to carefully simulate the duplication process. We'll create a brand new container and copy elements one by one from the original, inserting extra zeros whenever we find one in the original.
Here's how the algorithm would work step-by-step:
def duplicate_zeros_brute_force(original_array):
new_array = [0] * len(original_array)
new_array_index = 0
original_array_index = 0
# Iterate through the original array until we reach the end
while original_array_index < len(original_array):
# Copy the element from the original to the new array
new_array[new_array_index] = original_array[original_array_index]
new_array_index += 1
# Check if we've reached the end of the new array
if new_array_index == len(new_array):
break
# If we encounter a zero, duplicate it in the new array
if original_array[original_array_index] == 0:
new_array[new_array_index] = 0
new_array_index += 1
# Ensure that we are still within the bounds of the new array
if new_array_index == len(new_array):
break
original_array_index += 1
# Replace the original array with the modified new array
for index in range(len(original_array)):
original_array[index] = new_array[index]
The most efficient way to solve this is by working backwards. We figure out how big the final modified list will be and then adjust the original list from the end towards the beginning to avoid messing up parts we haven't touched yet.
Here's how the algorithm would work step-by-step:
def duplicate_zeros(array):
number_of_zeros = array.count(0)
modified_array_length = len(array) + number_of_zeros
original_array_length = len(array)
# Traverse backwards to modify in place.
current_index = original_array_length - 1
modified_index = modified_array_length - 1
while current_index >= 0 and modified_index >= 0:
if array[current_index] == 0:
# If we encounter a zero, duplicate it.
if modified_index < original_array_length:
array[modified_index] = 0
modified_index -= 1
if modified_index < original_array_length:
array[modified_index] = 0
else:
# Copy non-zero elements directly.
if modified_index < original_array_length:
array[modified_index] = array[current_index]
modified_index -= 1
current_index -= 1
| Case | How to Handle |
|---|---|
| Null or empty array | Return immediately without any processing to avoid NullPointerException or other errors. |
| Array containing only zeros | The algorithm correctly duplicates each zero, shifting the existing zeros to the right. |
| Array without any zeros | The algorithm does nothing, correctly leaving the array unchanged. |
| Array with a zero at the end | The algorithm correctly duplicates the zero, shifting the last element off the end. |
| Array with a zero at the beginning | The algorithm duplicates the zero and shifts all other elements to the right. |
| Array close to full capacity, with several zeros near the end | The algorithm handles this correctly, truncating any elements that go beyond the array length. |
| Array containing negative numbers and zeros | The algorithm only duplicates zeros and is not affected by negative numbers. |
| Large array with many zeros scattered throughout | The in-place modification ensures memory usage is efficient, handling large arrays without significant overhead. |