Given an unsorted array nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example:
(1) Given nums = [1, 5, 1, 1, 6, 4]
, one possible answer is [1, 4, 1, 5, 1, 6]
.
(2) Given nums = [1, 3, 2, 2, 3, 1]
, 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?
refer to some discussion post
use quickselect to find median, then use
public class Solution { public int vi(int n, int original) { int virtual = (1+ 2 *original)%(n|1); return virtual; } public void wiggleSort(int[] nums) { int len = nums.length; int median = findMedian(nums); int i=0, j=0, k=nums.length-1; while(j<=k) { if(nums[vi(len,j)]>median) { swap(nums, vi(len,i++), vi(len,j++)); }else if(nums[vi(len,j)]<median) { swap(nums, vi(len,k--), vi(len,j)); }else{ j++; } } } public int findMedian(int[] nums) { int len = nums.length; if(len%2 == 0) { return (findK(nums, len/2, 0, len-1) + findK(nums, len/2-1, 0, len-1))/2; }else { return findK(nums, len/2, 0, len-1); } } public int findK(int[] nums, int k, int s, int e) { if(s>=e) return nums[s]; int m = partition(nums, s, e); if(m == k) return nums[m]; else if(m<k) { return findK(nums, k, m+1, e); }else { return findK(nums, k, s, m-1); } } public int partition(int[] nums, int i, int j) { int pivot = nums[i]; int m = i; int n = i+1; while(n<=j) { if(nums[n]<pivot){ swap(nums, ++m, n); } n++; } swap(nums, i,m); return m; } public void swap(int[] nums, int a, int b) { int temp = nums[a]; nums[a] = nums[b]; nums[b] = temp; } }