原题链接在这里:https://leetcode.com/problems/wiggle-sort-ii/
题目:
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?
题解:
先通过Kth Largest Element in an Array找出median.
再把小于median的放在low位, 大于median的放在high位.
When we assign value to low index and high index, we need to consider n is odd and even, 2 cases.
e.g. 44456, median is 4, we need to put high index as n - 1, and every time high -=2.
4556, median is 5, here we need to put low index as n - 1, and every time low -= 2.
If for 4556, we also put high index as n - 1, we will get 5555 -> 4556, there are two 5 close to each other.
Note: eventually we need to assign res back to nums one by one, but not nums = res. Since it is checking heap, but not stack. nums is a variable in stack, it is pointing to realy memory in heap.
Time Complexity: O(n). Space: O(n).
AC Java:
1 class Solution { 2 public void wiggleSort(int[] nums) { 3 if(nums == null || nums.length < 2){ 4 return; 5 } 6 7 int n = nums.length; 8 int median = findK(nums, 0, n - 1, n / 2); 9 int [] res = new int[n]; 10 Arrays.fill(res, median); 11 12 if(n % 2 == 1){ 13 int low = 0; 14 int high = n - 2; 15 16 for(int num : nums){ 17 if(num < median){ 18 res[low] = num; 19 low += 2; 20 }else if(num > median){ 21 res[high] = num; 22 high -= 2; 23 } 24 } 25 }else{ 26 int low = n - 2; 27 int high = 1; 28 for(int num : nums){ 29 if(num < median){ 30 res[low] = num; 31 low -= 2; 32 }else if(num > median){ 33 res[high] = num; 34 high += 2; 35 } 36 } 37 } 38 39 40 for(int i = 0; i < n; i++){ 41 nums[i] = res[i]; 42 } 43 } 44 45 private int findK(int [] nums, int l, int r, int k){ 46 if(l >= r){ 47 return nums[l]; 48 } 49 50 int m = partition(nums, l, r); 51 if(m == k){ 52 return nums[m]; 53 }else if(m < k){ 54 return findK(nums, m + 1, r, k); 55 }else{ 56 return findK(nums, l, m - 1, k); 57 } 58 } 59 60 private int partition(int [] nums, int l, int r){ 61 int pivot = nums[l]; 62 while(l < r){ 63 while(l < r && nums[r] >= pivot){ 64 r--; 65 } 66 67 nums[l] = nums[r]; 68 69 while(l < r && nums[l] <= pivot){ 70 l++; 71 } 72 73 nums[r] = nums[l]; 74 } 75 76 nums[l] = pivot; 77 return l; 78 } 79 }
类似Wiggle Sort.