{x}
blog image

Array With Elements Not Equal to Average of Neighbors

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.

 

Example 1:

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:

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.

 

Constraints:

  • 3 <= nums.length <= 105
  • 0 <= nums[i] <= 105

Solution Explanation for Array With Elements Not Equal to Average of Neighbors

This problem asks us to rearrange an array of distinct integers such that no element is equal to the average of its neighbors. The most efficient solution leverages the property of distinct integers and sorting.

Approach:

  1. Sort the Array: We begin by sorting the input array nums in ascending order. This is crucial for the next step.

  2. Interleave Elements: After sorting, we create a new array ans. We populate ans by interleaving elements from the sorted array. We take the first half of the sorted nums and place them in the even-indexed positions of ans. The second half of the sorted nums is placed in the odd-indexed positions of ans.

  3. Guarantee of Condition: This interleaving guarantees that the condition "(nums[i-1] + nums[i+1]) / 2 != nums[i]" holds for all 1 <= i < n-1. Because the array is sorted, the neighbors of any element will be smaller and larger, respectively. Their average will almost certainly be distinct from the element itself.

Time and Space Complexity:

  • Time Complexity: The dominant operation is sorting the input array, which takes O(n log n) time, where n is the length of the array. The interleaving step takes O(n) time. Therefore, the overall time complexity is O(n log n).

  • Space Complexity: We create a new array ans of the same size as the input array. Therefore, the space complexity is O(n).

Code Examples:

The code examples below demonstrate this approach in several popular programming languages. They all follow the same fundamental steps: sort, then interleave. Minor differences exist in syntax and handling of array indexing.

Python3:

class Solution:
    def rearrangeArray(self, nums: List[int]) -> List[int]:
        nums.sort()
        n = len(nums)
        m = (n + 1) // 2
        ans = []
        for i in range(m):
            ans.append(nums[i])
            if i + m < n:
                ans.append(nums[i + m])
        return ans
 

Java:

class Solution {
    public int[] rearrangeArray(int[] nums) {
        Arrays.sort(nums);
        int n = nums.length;
        int m = (n + 1) >> 1; // Efficient bitwise right shift for division by 2
        int[] ans = new int[n];
        for (int i = 0, j = 0; i < n; i += 2, j++) {
            ans[i] = nums[j];
            if (j + m < n) {
                ans[i + 1] = nums[j + m];
            }
        }
        return ans;
    }
}

C++:

class Solution {
public:
    vector<int> rearrangeArray(vector<int>& nums) {
        ranges::sort(nums); //Using ranges::sort for conciseness (C++20)
        vector<int> ans;
        int n = nums.size();
        int m = (n + 1) / 2;
        for (int i = 0; i < m; ++i) {
            ans.push_back(nums[i]);
            if (i + m < n) {
                ans.push_back(nums[i + m]);
            }
        }
        return ans;
    }
};

Go:

func rearrangeArray(nums []int) (ans []int) {
	sort.Ints(nums)
	n := len(nums)
	m := (n + 1) / 2
	for i := 0; i < m; i++ {
		ans = append(ans, nums[i])
		if i+m < n {
			ans = append(ans, nums[i+m])
		}
	}
	return
}

TypeScript:

function rearrangeArray(nums: number[]): number[] {
    nums.sort((a, b) => a - b);
    const n = nums.length;
    const m = Math.floor((n + 1) / 2);
    const ans: number[] = [];
    for (let i = 0; i < m; i++) {
        ans.push(nums[i]);
        if (i + m < n) {
            ans.push(nums[i + m]);
        }
    }
    return ans;
}

These code snippets effectively implement the described algorithm, providing a solution with optimal time and space complexity. Remember to choose the language best suited to your environment and preferences.