Wiggle Sort II - Medium - L - Star
Published:
Question
- https://leetcode.com/problems/house-robber-iii/
Given an integer array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]….
You may assume the input array always has a valid answer.
Approach
- Median finding
- https://evelynn.gitbooks.io/google-interview/content/wiggle_sort_ii.html
Solution
class Solution {
public void wiggleSort(int[] nums) {
int median = findKthLargest(nums, (nums.length + 1) / 2);
int n = nums.length;
int left = 0, i = 0, right = n - 1;
while (i <= right) {
if (nums[newIndex(i,n)] > median) {
swap(nums, newIndex(left++,n), newIndex(i++,n));
}
else if (nums[newIndex(i,n)] < median) {
swap(nums, newIndex(right--,n), newIndex(i,n));
}
else {
i++;
}
}
}
private int findKthLargest(int[] nums, int k) {
k = nums.length - k;
int lo = 0;
int hi = nums.length - 1;
while (lo < hi) {
final int j = partition(nums, lo, hi);
if(j < k) {
lo = j + 1;
} else if (j > k) {
hi = j - 1;
} else {
break;
}
}
return nums[k];
}
private int partition(int[] nums, int left, int right) {
int i = left;
int j = right + 1;
while(true) {
while(i < right && nums[++i] < nums[left]);
while(j > left && nums[left] < nums[--j]);
if(i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, left, j);
return j;
}
private int newIndex(int index, int n) {
return (1 + 2*index) % (n | 1);
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}