Given an integer array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]....
You may assume the input array always has a valid answer.
Example 1:
Input: nums = [1,5,1,1,6,4]
Output: [1,6,1,5,1,4]
Explanation: [1,4,1,5,1,6] is also accepted.
Example 2:
Input: nums = [1,3,2,2,3,1]
Output: [2,3,1,3,1,2]
Constraints:
1 <= nums.length <= 5 * 104
0 <= nums[i] <= 5000
It is guaranteed that there will be an answer for the given input nums.
Follow Up: Can you do it in O(n) time and/or in-place with O(1) extra space?
Solutions
Solution 1
Thinking
We need \(nums[0]<nums[1]>nums[2]<\cdots\) and may reorder in place.
Sort, then fill even indices from the median downward and odd indices from the end downward. Reversed halves keep equal values from sitting next to each other.
1 2 3 4 5 6 7 8 9101112131415
classSolution:defwiggleSort(self,nums:List[int])->None:""" Do not return anything, modify nums in-place instead. """arr=sorted(nums)n=len(arr)i,j=(n-1)>>1,n-1forkinrange(n):ifk%2==0:nums[k]=arr[i]i-=1else:nums[k]=arr[j]j-=1
/** * @param {number[]} nums * @return {void} Do not return anything, modify nums in-place instead. */varwiggleSort=function(nums){letbucket=newArray(5001).fill(0);for(constvofnums){bucket[v]++;}constn=nums.length;letj=5000;for(leti=1;i<n;i+=2){while(bucket[j]==0){--j;}nums[i]=j;--bucket[j];}for(leti=0;i<n;i+=2){while(bucket[j]==0){--j;}nums[i]=j;--bucket[j];}};
Solution 2
Thinking
Method 1 sorts in \(O(n\log n)\) and uses an extra array. Values lie in \([0,5000]\): count-sort, then emit large values onto odd indices first and even indices next. Peaks get large numbers in linear time.
1 2 3 4 5 6 7 8 91011121314151617181920
classSolution:defwiggleSort(self,nums:List[int])->None:""" Do not return anything, modify nums in-place instead. """bucket=[0]*5001forvinnums:bucket[v]+=1n=len(nums)j=5000foriinrange(1,n,2):whilebucket[j]==0:j-=1nums[i]=jbucket[j]-=1foriinrange(0,n,2):whilebucket[j]==0:j-=1nums[i]=jbucket[j]-=1