Wiggle Sort II
Given an unsorted array nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example 1:
Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].
Example 2:
Input: nums = [1, 3, 2, 2, 3, 1]
Output: One possible answer is [2, 3, 1, 3, 1, 2].
Note: You may assume all input has valid answer.
Follow Up: Can you do it in O(n) time and/or in-place with O(1) extra space?
class Solution {
// O(NlogN) Time & O(N) Space Solution
public void wiggleSort(int[] nums) {
int[] copy = Arrays.copyOf(nums, nums.length);
Arrays.sort(copy);
int n = nums.length;
int left = (n + 1) / 2 - 1; // median index
int right = n - 1; // largest value index
for (int i = 0; i < nums.length; i++) { // copy large values on odd indexes
if (i % 2 == 1) {
nums[i] = copy[right];
right--;
} else { // copy values decremeting from median on even indexes
nums[i] = copy[left];
left--;
}
}
}
// O(n) average time and O(1) space Solution
public void swap(int[] A, int i, int j) {
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
public int findKthLargest(int[] A, int k) {
k = A.length - k; // convert to index of k largest
int left = 0, right = A.length - 1;
while (left <= right) {
// Choosing left index as pivot element
int i = left;
for (int j = left + 1; j <= right; j++)
if (A[j] < A[left]) {
i++;
swap(A, j, i);
}
// 'i' will be the head of list of element < pivot
swap(A, left, i);
if (k < i)
right = i - 1;
else if (k > i)
left = i + 1;
else
return A[i];
}
return -1; // k is invalid
}
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++;
}
}
// What n|1 does it that it gets the next odd number to n if it was even
private int newIndex(int index, int n) {
return (1 + 2 * index) % (n | 1);
}
}
Last updated