Wiggle Sort I & II
Given an unsorted array nums
, reorder it in-place such that
nums[0] <= nums[1] >= nums[2] <= nums[3]....
Notice
Please complete the problem in-place.
Example
Given nums = [3, 5, 2, 1, 6, 4]
, one possible answer is [1, 6, 2, 5, 3, 4]
.
分析:
排序,从第三个开始,把它和前一个数互换。
1 public class Solution { 2 /** 3 * @param nums a list of integer 4 * @return void 5 */ 6 public void wiggleSort(int[] nums) { 7 if (nums == null || nums.length <= 1) return; 8 9 Arrays.sort(nums); 10 11 for(int i = 2; i < nums.length; i+=2){ 12 int tmp = nums[i-1]; 13 nums[i-1] = nums[i]; 14 nums[i] = tmp; 15 } 16 } 17 }
Given an unsorted array nums
, reorder it such that
nums[0] < nums[1] > nums[2] < nums[3]....
Notice
You may assume all input has valid answer.
Example
Given nums = [1, 5, 1, 1, 6, 4]
, one possible answer is [1, 4, 1, 5, 1, 6]
.
Given nums = [1, 3, 2, 2, 3, 1]
, one possible answer is [2, 3, 1, 3, 1, 2]
.
分析:
先sort, 然后用一个指针指向中间那个数,另一个指针指向最末尾那个数,然后依次把数放入到一个新数组里.
1 public class Solution { 2 /** 3 * @param nums a list of integer 4 * @return void 5 */ 6 public void wiggleSort(int[] nums) { 7 if (nums == null || nums.length <= 1) return; 8 Arrays.sort(nums); 9 int[] temp = new int[nums.length]; 10 11 // 两个指针 p, q. p 指向中间那个数,q指向最右边那个数。 12 // 不断交替把数放在temp数组里。 13 int mid = (temp.length + 1) / 2 - 1; 14 int end = temp.length - 1; 15 16 for (int i = 0; i < temp.length; i++) { 17 if ((i & 1) == 0) { 18 temp[i] = nums[mid--]; 19 } else { 20 temp[i] = nums[end--]; 21 } 22 } 23 24 // put the numbers back to nums. 25 for (int i = 0; i < temp.length; i++) { 26 nums[i] = temp[i]; 27 } 48 } 49 }
还有一种方法,先把array中的median找出来,然后把小于median和大于median的值交叉放入新数组中。
该方法来自: http://buttercola.blogspot.com/2016/01/leetcode-wiggle-sort-ii.html
1 public class Solution { 2 public void wiggleSort(int[] nums) { 3 if (nums == null || nums.length <= 1) { 4 return; 5 } 6 7 int n = nums.length; 8 9 // Step 1: Find median of the array, return the index of the median 10 int median = findMedian(nums, 0, n - 1, (n - 1) / 2); 11 12 // Step 2: 3-way sort, put median in the middle, 13 // numbers less than median on the left, 14 // numbers greater than median on the right 15 int[] temp = new int[n]; 16 int left = 0; 17 int right = n - 1; 18 19 for (int i = 0; i < n; i++) { 20 if (nums[i] < nums[median]) { 21 temp[left] = nums[i]; 22 left++; 23 } else if (nums[i] > nums[median]) { 24 temp[right] = nums[i]; 25 right--; 26 } 27 } 28 29 // add median into the middle 30 for (int i = left; i <= right; i++) { 31 temp[i] = nums[median]; 32 } 33 34 // Step 3: wiggle sort 35 left = (n - 1) / 2; 36 right = n - 1; 37 38 for (int i = 0; i < n; i++) { 39 if ((i & 1) == 0) { 40 nums[i] = temp[left]; 41 left--; 42 } else { 43 nums[i] = temp[right]; 44 right--; 45 } 46 } 47 } 48 49 private int findMedian(int[] nums, int lo, int hi, int k) { 50 if (lo >= hi) { 51 return lo; 52 } 53 54 int pivot = partition(nums, lo, hi); 55 if (pivot == k) { 56 return pivot; 57 } 58 59 if (pivot > k) { 60 return findMedian(nums, lo, pivot - 1, k); 61 } else { 62 return findMedian(nums, pivot + 1, hi, k); 63 } 64 } 65 66 private int partition(int[] nums, int lo, int hi) { 67 int pivot = nums[lo]; 68 int i = lo + 1; 69 int j = hi; 70 71 while (i <= j) { 72 while (i <= j && nums[i] < pivot) { 73 i++; 74 } 75 76 while (i <= j && nums[j] >= pivot) { 77 j--; 78 } 79 80 if (i <= j) { 81 swap(nums, i, j); 82 } 83 } 84 85 swap(nums, lo, j); 86 87 return j; 88 } 89 90 private void swap(int[] nums, int i, int j) { 91 int temp = nums[i]; 92 nums[i] = nums[j]; 93 nums[j] = temp; 94 } 95 }