Given an integer array nums
, rearrange the elements of nums
so that no element is equal to the average of its immediate neighbors. In other words, for every index i
(where 1 ≤ i < nums.length - 1
), you must ensure:
nums[i] ≠ (nums[i-1] + nums[i+1]) / 2
nums
must be used exactly once (no reusing or omitting elements).
The brute-force approach would be to check all possible permutations of nums
and see if any arrangement satisfies the condition. However, this quickly becomes infeasible as the number of permutations grows factorially with the array size.
Instead, let's think about why an element might be equal to the average of its neighbors. This happens when the element is "between" two values in a sorted sense. For example, if the neighbors are the smallest and largest, the middle value would be their average. So, to avoid this, we can try to arrange the numbers so that large and small values alternate, preventing any value from being the average of its neighbors.
This leads us to consider sorting the array and then interleaving the smallest and largest halves, so that adjacent numbers are as different as possible.
To construct a valid arrangement efficiently, follow these steps:
nums
in ascending order.This approach works because, by separating similar values, we avoid having three consecutive values that form an arithmetic progression (which would cause the middle one to be the average of its neighbors).
Let's consider nums = [1, 2, 3, 4, 5, 6]
.
nums
(already sorted): [1, 2, 3, 4, 5, 6]
[1, 2, 3]
[4, 5, 6]
Result: [1, 4, 2, 5, 3, 6]
Condition satisfied for all indices.
By sorting the array and interleaving its smallest and largest halves, we ensure that no element is the average of its neighbors. This approach is both efficient and simple to implement, avoiding the need to check all permutations. The key insight is that separating similar values prevents the formation of arithmetic progressions, which would otherwise violate the problem's condition.
class Solution:
def rearrangeArray(self, nums):
nums.sort()
n = len(nums)
res = []
mid = (n + 1) // 2
left = nums[:mid]
right = nums[mid:]
l, r = 0, 0
for i in range(n):
if i % 2 == 0:
res.append(left[l])
l += 1
else:
res.append(right[r])
r += 1
return res
class Solution {
public:
vector<int> rearrangeArray(vector<int>& nums) {
sort(nums.begin(), nums.end());
int n = nums.size();
vector<int> res(n);
int mid = (n + 1) / 2;
int l = 0, r = mid;
for (int i = 0; i < n; ++i) {
if (i % 2 == 0) {
res[i] = nums[l++];
} else {
res[i] = nums[r++];
}
}
return res;
}
};
class Solution {
public int[] rearrangeArray(int[] nums) {
Arrays.sort(nums);
int n = nums.length;
int[] res = new int[n];
int mid = (n + 1) / 2;
int l = 0, r = mid;
for (int i = 0; i < n; i++) {
if (i % 2 == 0) {
res[i] = nums[l++];
} else {
res[i] = nums[r++];
}
}
return res;
}
}
var rearrangeArray = function(nums) {
nums.sort((a, b) => a - b);
const n = nums.length;
const res = [];
const mid = Math.floor((n + 1) / 2);
let l = 0, r = mid;
for (let i = 0; i < n; i++) {
if (i % 2 === 0) {
res.push(nums[l++]);
} else {
res.push(nums[r++]);
}
}
return res;
};