from collections import Counter
class Solution:
def canReorderDoubled(self, arr):
count = Counter(arr)
for x in sorted(count, key=abs):
if count[x] > count[2 * x]:
return False
count[2 * x] -= count[x]
return True
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <cmath>
using namespace std;
class Solution {
public:
bool canReorderDoubled(vector<int>& arr) {
unordered_map<int, int> count;
for (int x : arr) count[x]++;
vector<int> keys;
for (auto &kv : count) keys.push_back(kv.first);
sort(keys.begin(), keys.end(), [](int a, int b) { return abs(a) < abs(b); });
for (int x : keys) {
if (count[x] > count[2 * x]) return false;
count[2 * x] -= count[x];
}
return true;
}
};
import java.util.*;
class Solution {
public boolean canReorderDoubled(int[] arr) {
Map<Integer, Integer> count = new HashMap<>();
for (int x : arr)
count.put(x, count.getOrDefault(x, 0) + 1);
List<Integer> keys = new ArrayList<>(count.keySet());
keys.sort(Comparator.comparingInt(Math::abs));
for (int x : keys) {
if (count.get(x) > count.getOrDefault(2 * x, 0))
return false;
count.put(2 * x, count.getOrDefault(2 * x, 0) - count.get(x));
}
return true;
}
}
var canReorderDoubled = function(arr) {
let count = new Map();
for (let x of arr) {
count.set(x, (count.get(x) || 0) + 1);
}
let keys = Array.from(count.keys());
keys.sort((a, b) => Math.abs(a) - Math.abs(b));
for (let x of keys) {
if (count.get(x) > (count.get(2 * x) || 0)) return false;
count.set(2 * x, (count.get(2 * x) || 0) - count.get(x));
}
return true;
};
Given an array arr
of integers, your task is to determine if it is possible to reorder the array so that for every element x
, there exists another element y
such that y = 2 * x
. In other words, you need to pair up all elements in the array so that one element in each pair is exactly double the other. Each element in the array can be used only once in a pair. If such a reordering and pairing is possible, return true
; otherwise, return false
.
At first glance, the problem seems to suggest checking all possible pairings, which would be very inefficient. If we try to brute-force all possible pairs, the number of combinations grows rapidly as the array size increases. We need a more efficient way to check if every number can be paired with its double, and to do so without reusing any elements.
A key insight is to use counting: for each number, we want to know how many times it appears and how many times its double appears. But we must be careful with negative numbers and zeros, since doubling negatives or zeros has subtle effects. Sorting the array by absolute value helps ensure we always try to pair smaller numbers first, which avoids running into situations where we can't find a double for a smaller number because it was already used in a previous pair.
Using a hash map (or dictionary) to count occurrences, and then processing the numbers in order of their absolute values, allows us to efficiently form valid pairs or determine if it's impossible.
x
in the sorted list:
2 * x
to pair with all occurrences of x
(i.e., is count[2 * x] >= count[x]
?).false
immediately because pairing is impossible.count[x]
from count[2 * x]
to indicate those numbers have been used in pairs.true
.
This approach leverages the efficiency of hash maps for counting and the logic of absolute-value sorting to ensure correctness across positive, negative, and zero values.
Let's walk through the example arr = [4, -2, 2, -4]
:
true
.
The "Array of Doubled Pairs" problem can be solved efficiently by counting occurrences of each number and then attempting to pair each number with its double, processing numbers in order of their absolute value. This strategy avoids brute-force pairing and handles all cases, including negative numbers and zeros, in O(n log n) time. The key insight is to use a hash map for counting and to always pair smaller absolute values first, ensuring elements are not reused and all pairs are valid.