Given an integer array of even length arr
, return true
if it is possible to reorder arr
such that arr[2 * i + 1] = 2 * arr[2 * i]
for every 0 <= i < len(arr) / 2
, or false
otherwise.
Example 1:
Input: arr = [3,1,3,6] Output: false
Example 2:
Input: arr = [2,1,2,6] Output: false
Example 3:
Input: arr = [4,-2,2,-4] Output: true Explanation: We can take two groups, [-2,-4] and [2,4] to form [-2,-4,2,4] or [2,4,-2,-4].
Constraints:
2 <= arr.length <= 3 * 104
arr.length
is even.-105 <= arr[i] <= 105
The problem asks whether we can reorder an array of even length such that each element is half the value of the next element. The solution uses a greedy approach combined with hash table (or map) and sorting for efficient processing.
Approach:
Frequency Counting: We first count the frequency of each element in the input array arr
using a hash map (dictionary in Python). This allows for quick lookup of element counts.
Handling Zeroes: If the count of 0 is odd, it's impossible to form pairs, so we return False
.
Sorted Processing: We sort the unique elements of the array based on their absolute values. This is crucial because we want to check for pairs starting from the smallest numbers to avoid conflicts. Smaller numbers are processed first so that if a number has a corresponding double, it's more likely to be found.
Greedy Pairing: We iterate through the sorted unique elements. For each element x
, we check if its double (2 * x
) exists and if its frequency is at least as large as the frequency of x
.
If 2 * x
has a frequency smaller than x
, it means we don't have enough doubles to pair with all instances of x
, so we return False
.
If the condition is met, we update the frequency of 2 * x
by subtracting the frequency of x
. This simulates pairing the elements and removes them from consideration for future pairings.
Final Result: If the loop completes without returning False
, it means we successfully formed all pairs, and we return True
.
Time Complexity Analysis:
Therefore, the overall time complexity is dominated by the sorting step, making it O(k log k) or O(n log n) in the worst case. In many scenarios, the number of unique elements (k) will be much smaller than n, making it more efficient than a purely brute-force approach.
Space Complexity Analysis:
The space complexity is O(k) to store the frequency map and the sorted unique elements, where k is the number of unique elements in the array. Again, in the worst case, k could be n, but often it will be smaller.
Code Examples (with explanations inline):
The provided code examples in Python, Java, C++, and Go all implement this approach. The logic is the same across languages; only syntax differs. For example, let's focus on the Python code:
class Solution:
def canReorderDoubled(self, arr: List[int]) -> bool:
freq = Counter(arr) # Count element frequencies using Counter (efficient for this task)
if freq[0] % 2: # Check if the count of 0 is odd
return False
for x in sorted(freq, key=abs): # Iterate through sorted unique elements by absolute value
if freq[x << 1] < freq[x]: # Check if enough doubles exist for x
return False
freq[x << 1] -= freq[x] # Update frequency of double after pairing
return True
The other languages use similar structures: hash maps (HashMap
in Java, unordered_map
in C++, map
in Go) to count frequencies and then iterating through sorted keys to perform the greedy pairing. The sorted
function in Python and equivalent functions in other languages handle the sorting by absolute value.