public class Solution {
public void wiggleSort(int[] nums) {
int n = nums.length;
int median = findKthLargest(nums, (n + 1) / 2);
int left = 0, right = n - 1, i = 0;
while (i <= right) {
if (nums[getIndex(i, n)] > median) {
swap(nums, getIndex(i, n), getIndex(left, n));
left++;
i++;
} else if (nums[getIndex(i, n)] < median) {
swap(nums, getIndex(i, n), getIndex(right, n));
right--;
} else {
i++;
}
}
}
private int getIndex(int i, int n) {
return (1 + 2 * i) % (n | 1);
}
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
private int findKthLargest(int[] nums, int k) {
k = nums.length - k;
int left = 0, right = nums.length - 1;
while (left < right) {
int pos = partition(nums, left, right);
if (pos == k) {
break;
} else if (pos < k) {
left = pos + 1;
} else {
right = pos - 1;
}
}
return nums[k];
}
private int partition(int[] nums, int left, int right) {
int i = left, j = right + 1;
int pivot = nums[left];
while (true) {
while (i < right && nums[++i] < pivot);
while (j > left && nums[--j] >= pivot);
if (i >= j) break;
swap(nums, i, j);
}
swap(nums, left, j);
return j;
}
}