Difficult part is how to rearrange the new array. See explanation.
class Solution {
public void wiggleSort(int[] nums) {
// edge case
if (nums == null || nums.length == 0) return;
int n = nums.length;
int mid = kthElement(nums, (n+1)/2); // find the middle point, O(n) time
int[] copy = new int[n];
// bigger -> odd, left to right, smaller -> even, right to left
int odd = 1, even = n % 2 == 0 ? n - 2 : n - 1;
for (int i = 0; i < n; i++) {
if (nums[i] > mid) {
copy[odd] = nums[i];
odd += 2;
}
if (nums[i] < mid) {
copy[even] = nums[i];
even -= 2;
}
}
// fill mid to the rest. Deal with equal elements.
while (odd < n) {
copy[odd] = mid;
odd += 2;
}
while (even >= 0) {
copy[even] = mid;
even -= 2;
}
// copy back
for (int i = 0; i < n; i++) {
nums[i] = copy[i];
}
}
private int kthElement(int[] nums, int k) {
int l = 0, r = nums.length - 1, res = 0;
while (l <= r) {
int cut = partition(nums, l, r);
if (cut + 1 == k) {
res = nums[cut];
break;
} else if (k < cut + 1) {
r = cut - 1;
} else {
l = cut + 1;
}
}
return res;
}
private int partition(int[] nums, int start, int end) {
if (start == end) return start;
int pivot = nums[start], l = start + 1, r = end;
while (l <= r) {
while (l <= r && nums[l] > pivot) l++;
while (l <= r && nums[r] < pivot) r--;
if (l <= r) {
swap(nums, l, r);
l++;
r--;
}
}
swap(nums, start, r);
return r;
}
private void swap(int[] nums, int a, int b) {
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
}
/*
O(N) time and space
*/
ac2: sort
O(nlogn) time, but it's faster than previous solution, weird
class Solution {
public void wiggleSort(int[] nums) {
// edge case
if (nums == null || nums.length == 0) return;
int n = nums.length;
Arrays.sort(nums);
int[] copy = nums.clone();
int i = n - 1;
int idx = 1;
while (idx < n) {
nums[idx] = copy[i];
idx += 2;
i--;
}
idx = 0;
while (idx < n) {
nums[idx] = copy[i];
idx += 2;
i--;
}
}
}
// O(NlogN) time, O(N) space
ac3: index mapping
0(N) time, O(1) space. But it's insanely hard to understand. See this post: https://leetcode.com/problems/wiggle-sort-ii/discuss/77682/step-by-step-explanation-of-index-mapping-in-java.