An integer array original
is transformed into a doubled array changed
by appending twice the value of every element in original
, and then randomly shuffling the resulting array.
Given an array changed
, return original
if changed
is a doubled array. If changed
is not a doubled array, return an empty array. The elements in original
may be returned in any order.
Example 1:
Input: changed = [1,3,4,2,6,8] Output: [1,3,4] Explanation: One possible original array could be [1,3,4]: - Twice the value of 1 is 1 * 2 = 2. - Twice the value of 3 is 3 * 2 = 6. - Twice the value of 4 is 4 * 2 = 8. Other original arrays could be [4,3,1] or [3,1,4].
Example 2:
Input: changed = [6,3,0,1] Output: [] Explanation: changed is not a doubled array.
Example 3:
Input: changed = [1] Output: [] Explanation: changed is not a doubled array.
Constraints:
1 <= changed.length <= 105
0 <= changed[i] <= 105
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 strategy for finding the original array involves checking every possible combination of numbers to see if one of those combinations, when doubled, produces the given doubled array. It's like trying every possible puzzle piece to see if it fits. We systematically check all possibilities.
Here's how the algorithm would work step-by-step:
def find_original_array_brute_force(doubled_array):
array_length = len(doubled_array)
if array_length % 2 != 0:
return []
for i in range(array_length):
potential_original = []
remaining_numbers = doubled_array[:]
potential_original.append(remaining_numbers[i])
del remaining_numbers[i]
temp_remaining_numbers = remaining_numbers[:]
temp_potential_original = potential_original[:]
while len(temp_potential_original) <= array_length // 2:
found_match = False
for j in range(len(temp_remaining_numbers)):
if temp_remaining_numbers[j] == 2 * temp_potential_original[-1]:
del temp_remaining_numbers[j]
found_match = True
# Only append if a match is found
if len(temp_remaining_numbers) > 0:
temp_potential_original.append(temp_remaining_numbers[0])
del temp_remaining_numbers[0]
break
if not found_match:
break
if len(temp_potential_original) == array_length // 2 and found_match:
return potential_original
return []
The key to solving this problem efficiently is to work backwards from the largest numbers. We use a counting method to keep track of how many times each number appears, and then intelligently pair each number with its double to reconstruct the original array.
Here's how the algorithm would work step-by-step:
def find_original_array(doubled_array):
number_counts = {}
for number in doubled_array:
number_counts[number] = number_counts.get(number, 0) + 1
doubled_array.sort()
original_array = []
for number in reversed(doubled_array):
if number_counts[number] == 0:
continue
double_value = number / 2
#If number is odd, then it can't be double of anything.
if number % 2 != 0:
return []
# This makes sure that the number can be formed from a doubling.
if double_value not in number_counts or number_counts[double_value] == 0:
return []
original_array.append(int(double_value))
# Reduce the counts of the original number and its double.
number_counts[number] -= 1
number_counts[double_value] -= 1
return original_array
Case | How to Handle |
---|---|
Null input array | Return an empty array immediately to avoid NullPointerException. |
Empty input array | Return an empty array immediately as no original array can be formed. |
Input array with an odd number of elements | Return an empty array immediately because a doubled array must have an even number of elements. |
Input array contains zero values | Handle zero values carefully since 2*0 is 0 and requires special counting/handling to avoid incorrect pairings. |
Input array contains negative numbers | Sort the input array, then iterate and verify the existence of doubled negative values correctly. |
Large numbers in the array that could cause integer overflow when doubled | Consider using a larger data type (e.g., long) or implement overflow checking if the doubled value is used in calculations. |
Input array contains duplicate values where some are doubled and some are not | The algorithm should correctly identify pairs even with duplicates by using a frequency map. |
No valid original array exists | The algorithm should return an empty array when after processing the entire input, not all numbers could be paired appropriately. |