Problem

You are given a 0-indexed array nums of distinct integers. You want to rearrange the elements in the array such that every element in the rearranged array is not equal to the average of its neighbors.

More formally, the rearranged array should have the property such that for every i in the range 1 <= i < nums.length - 1(nums[i-1] + nums[i+1]) / 2 is not equal to nums[i].

Return any rearrangement of nums that meets the requirements.

Examples

Example 1:

1
2
3
4
5
6
Input: nums = [1,2,3,4,5]
Output: [1,2,4,5,3]
Explanation:
When i=1, nums[i] = 2, and the average of its neighbors is (1+4) / 2 = 2.5.
When i=2, nums[i] = 4, and the average of its neighbors is (2+5) / 2 = 3.5.
When i=3, nums[i] = 5, and the average of its neighbors is (4+3) / 2 = 3.5.

Example 2:

1
2
3
4
5
6
Input: nums = [6,2,0,9,7]
Output: [9,7,6,2,0]
Explanation:
When i=1, nums[i] = 7, and the average of its neighbors is (9+6) / 2 = 7.5.
When i=2, nums[i] = 6, and the average of its neighbors is (7+2) / 2 = 4.5.
When i=3, nums[i] = 2, and the average of its neighbors is (6+0) / 2 = 3.

Solution

Method 1 - Using Wiggle Sort

We can use Wiggle Sort 1 and Wiggle Sort 2 - No Adjacent Duplicates algorithms smartly. If we make sure that nums[i-1] < nums[i] > nums[i+1], i.e. - a < b > c < d > e < f, we are good to go.

1
2
3
4
5
6
7
8
9
public int[] rearrangeArray(int[] nums) {
	Arrays.sort(nums);
	for (int i = 1; i < nums.length; i += 2) {
		int tmp = nums[i];
		nums[i] = nums[i - 1];
		nums[i - 1] = tmp;
	}
	return nums;
}

Time complexity - O(nlogn)

Method 2 - Using MinHeap

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public int[] rearrangeArray(int[] nums) {
	Queue<Integer> minHeap = new PriorityQueue<>();
	for (int num:nums) {
		minHeap.add(num);
	}
	for (int i = 1; i < nums.length; i=i+2) {
	   nums[i]  = minHeap.poll();
	}
	for (int i = 0; i < nums.length; i=i+2) {
		nums[i]  = minHeap.poll();
	}
	return nums;
}

Method 3 - Sorting and Keeping Numbers Greater Than Median at Odd Indexs

1
2
3
4
5
6
7
8
9
 public static int[] rearrangeArrayWithSorting1(int[] nums) {
	int len = nums.length;
	Arrays.sort(nums);
	int medianIndex = len - len / 2;
	for (int i = 1; i < nums.length && medianIndex < nums.length; i += 2, medianIndex++) {
		swap(nums, i, medianIndex);
	}
	return nums;
}

Method 4 - Without Sorting

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 public static int[] rearrangeArray(int[] nums) {
   int n = nums.length;
   for (int i = 1; i < n - 1; i++) {
	   if (2 * nums[i] == (nums[i - 1] + nums[i + 1])) {
		   swap(nums, i, i + 1);
	   }
   }
   for (int i = n - 2; i > 0; i--) {
	   if (2 * nums[i] == (nums[i - 1] + nums[i + 1])) {
		   swap(nums, i, i - 1);
	   }
   }
   return nums;
}

public static void swap(int[] nums, int a, int b) {
   int tmp = nums[a];
   nums[a] = nums[b];
   nums[b] = tmp;
}