Difficult part is how to rearrange the new array. See explanation.
classSolution {publicvoidwiggleSort(int[] nums) {// edge caseif (nums ==null||nums.length==0) return;int n =nums.length;int mid =kthElement(nums, (n+1)/2); // find the middle point, O(n) timeint[] copy =newint[n];// bigger -> odd, left to right, smaller -> even, right to leftint 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 backfor (int i =0; i < n; i++) { nums[i] = copy[i]; } }privateintkthElement(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; } elseif (k < cut +1) { r = cut -1; } else { l = cut +1; } }return res; }privateintpartition(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; }privatevoidswap(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
classSolution {publicvoidwiggleSort(int[] nums) {// edge caseif (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.