class Solution:
def wiggleSort(self, nums):
n = len(nums)
sorted_nums = sorted(nums)
mid = (n + 1) // 2
left = sorted_nums[:mid][::-1]
right = sorted_nums[mid:][::-1]
for i in range(n):
if i % 2 == 0:
nums[i] = left[i // 2]
else:
nums[i] = right[i // 2]
class Solution {
public:
void wiggleSort(vector<int>& nums) {
int n = nums.size();
vector<int> sorted(nums);
sort(sorted.begin(), sorted.end());
int mid = (n + 1) / 2;
int left = mid - 1, right = n - 1;
for (int i = 0; i < n; ++i) {
if (i % 2 == 0)
nums[i] = sorted[left--];
else
nums[i] = sorted[right--];
}
}
};
class Solution {
public void wiggleSort(int[] nums) {
int n = nums.length;
int[] sorted = nums.clone();
Arrays.sort(sorted);
int mid = (n + 1) / 2;
int left = mid - 1, right = n - 1;
for (int i = 0; i < n; ++i) {
if (i % 2 == 0)
nums[i] = sorted[left--];
else
nums[i] = sorted[right--];
}
}
}
var wiggleSort = function(nums) {
let n = nums.length;
let sorted = [...nums].sort((a, b) => a - b);
let mid = Math.floor((n + 1) / 2);
let left = sorted.slice(0, mid).reverse();
let right = sorted.slice(mid).reverse();
for (let i = 0; i < n; ++i) {
nums[i] = (i % 2 === 0) ? left[Math.floor(i / 2)] : right[Math.floor(i / 2)];
}
};
Given an unsorted array of integers nums
, rearrange the elements in-place to satisfy the following "wiggle" property:
nums[0] < nums[1] > nums[2] < nums[3] > nums[4] ...
In other words, every odd-indexed element should be greater than its neighbors, and every even-indexed element should be less than its neighbors.
Constraints:
nums
).nums = [1, 5, 1, 1, 6, 4]
[1, 6, 1, 5, 1, 4]
(other valid outputs are possible)
At first glance, the problem seems similar to sorting, but with a twist: the numbers must alternate between "less than" and "greater than" their neighbors. One might think about generating all possible permutations and checking which ones satisfy the wiggle condition, but this is highly inefficient for large arrays.
A more systematic approach involves sorting the array to get the order of values, then distributing the largest and smallest elements in such a way that the wiggle property is preserved. The main idea is to ensure that the largest available numbers occupy the odd indices (peaks), and the smaller numbers fill the even indices (valleys).
This leads us to think about splitting the sorted array in half and interleaving the two halves in reverse order, ensuring the wiggle pattern is preserved. The challenge is to do this efficiently and in-place, without using extra space if possible.
Let's break down the steps to solve the problem efficiently:
nums
. This allows us to easily access the smallest and largest elements.nums
to satisfy the in-place requirement.
Let's use the sample input nums = [1, 5, 1, 1, 6, 4]
.
Step 1: Sort the array: [1, 1, 1, 4, 5, 6]
Step 2: Split into halves:
[1, 1, 1]
[4, 5, 6]
[1, 1, 1]
[6, 5, 4]
[1, 6, 1, 5, 1, 4]
nums[0] < nums[1] > nums[2] < nums[3] > nums[4] < nums[5]
.
Brute-force approach:
Wiggle Sort II asks us to rearrange an array so that it alternates between valleys and peaks. The most efficient and clear solution involves sorting the array, splitting it into two halves, reversing both, and interleaving the values to ensure the wiggle property holds. This approach is elegant because it leverages sorting to organize values, and simple index logic to distribute them correctly. The result is an O(n log n) time, O(n) space solution that is both easy to implement and understand.