publicstaticvoidwiggleSort(int[] nums) {if (nums ==null||nums.length<2) {return; }int[] tmp =Arrays.copyOf(nums,nums.length);// this method use nlogn time & n spaceArrays.sort(tmp);int mid = (nums.length-1) /2;int end =nums.length-1;for (int i =0; i <nums.length; i++) { nums[i] = (i %2==0) ? tmp[mid--] : tmp[end--]; }}
follow up:这个难度在于要用quick select找中位数,然后把数组劈开两半。然后跟上面同理可得结果。但普通的quick select是不能通过OJ的,因为我们要保证重复的元素都集中在中间才行。所以quick select里要用3 way partition。这个中间要用一个arraylist来暂存答案,所以用了O(n)space(这题考点太多太崩溃,O(1)space的virtual index wiring简直理解不能,完爆脑容量)
publicvoidwiggleSort(int[] nums) {if (nums ==null||nums.length==0) {return; }int len =nums.length;// quick select to find middle pointint mid =quickSelect(nums, len /2);if (len %2==0) { mid = mid -1; }int smInd = mid;int bgInd = len -1;// rearrange the arrayArrayList<Integer> tmp =newArrayList<>();for (int i =0; i < len; i++) {if (i %2==0) {tmp.add(nums[smInd--]); } else {tmp.add(nums[bgInd--]); } }int ind =0;// put result back to the original arrayfor (Integer elem : tmp) { nums[ind++] = elem; }}privateintquickSelect(int[] nums,int k) {int start =0;int end =nums.length-1;int[] bounds =patition(nums, start, end);while (start < end && (k < bounds[0] || k > bounds[1])) {if (k < bounds[0]) { end = bounds[0] -1; } elseif (k > bounds[1]) { start = bounds[1] +1; } bounds =patition(nums, start, end); }return k;}privateint[] patition(int[] nums,int start,int end) {int left = start;int right = end;int i = start;int pivot = nums[left];while (i <= right) {if (nums[i] < pivot) {swap(i, left, nums); i++; left++; } elseif (nums[i] == pivot) { i++; } else {swap(i, right, nums); right--; } }int[] res =newint[2]; res[0] = left; res[1] = right;return res;}privatevoidswap(int i,int j,int[] nums) {int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp;}