[LeetCode] 324. Wiggle Sort II 摆动排序 II
Given an unsorted array nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example 1:
nums = [1, 5, 1, 1, 6, 4]
[1, 4, 1, 5, 1, 6]
Example 2:
nums = [1, 3, 2, 2, 3, 1]
[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?
280. Wiggle Sort 的变形,这题nums[0] < nums[1] > nums[2] < nums[3]...
.里面没有等号。
解法1:先对数组进行排序, 然后从左往右奇数索引位置放大于中位数的数, 然后从右往左在偶数索引位置放小于中位数的数, 剩下的位置都放中位数. 其T: O(nlog(n)), S: O(n).
解法2:利用quickSelect算法,从未经排序的数组nums中选出中位数mid,以中位数mid为界,将大于mid的元素排列在ix的较小部分,而将小于mid的元素排列在ix的较大部分。T: O(n), S: O(1)
解法3:three-way partitioning,variant of 75. Sort Colors
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public void wiggleSort( int [] nums) { int median = findKthLargest(nums, (nums.length + 1 ) / 2 ); int n = nums.length; int left = 0 , i = 0 , right = n - 1 ; while (i <= right) { if (nums[newIndex(i,n)] > median) { swap(nums, newIndex(left++,n), newIndex(i++,n)); } else if (nums[newIndex(i,n)] < median) { swap(nums, newIndex(right--,n), newIndex(i,n)); } else { i++; } } } private int newIndex( int index, int n) { return ( 1 + 2 *index) % (n | 1 ); } |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | void wiggleSort(vector< int >& nums) { int n = nums.size(); // Find a median. auto midptr = nums.begin() + n / 2 ; nth_element(nums.begin(), midptr, nums.end()); int mid = *midptr; // Index-rewiring. #define A(i) nums[( 1 + 2 *(i)) % (n| 1 )] // 3-way-partition-to-wiggly in O(n) time with O(1) space. int i = 0 , j = 0 , k = n - 1 ; while (j <= k) { if (A(j) > mid) swap(A(i++), A(j++)); else if (A(j) < mid) swap(A(j), A(k--)); else j++; } } |
Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class Solution { public void wiggleSort( int [] nums) { int medium = findMedium(nums, 0 , nums.length - 1 , (nums.length + 1 ) >> 1 ); int s = 0 , t = nums.length - 1 , mid_index = (nums.length + 1 ) >> 1 ; int [] temp = new int [nums.length]; for ( int i = 0 ; i < nums.length; i++) { if (nums[i] < medium) temp[s++] = nums[i]; else if (nums[i] > medium) temp[t--] = nums[i]; } while (s < mid_index) temp[s++] = medium; while (t >= mid_index) temp[t--] = medium; t = nums.length; for ( int i = 0 ; i < nums.length; i++) nums[i] = (i & 1 ) == 0 ? temp[--s] : temp[--t]; } private int findMedium( int [] nums, int L, int R, int k) { if (L >= R) return nums[R]; int i = partition(nums, L, R); int cnt = i - L + 1 ; if (cnt == k) return nums[i]; return cnt > k ? findMedium(nums, L, i - 1 , k) : findMedium(nums, i + 1 , R, k - cnt); } private int partition( int [] nums, int L, int R) { int val = nums[L]; int i = L, j = R + 1 ; while ( true ) { while (++i < R && nums[i] < val) ; while (--j > L && nums[j] > val) ; if (i >= j) break ; swap(nums, i, j); } swap(nums, L, j); return j; } private void swap( int [] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } } |
Python:
1 2 3 4 5 6 7 8 9 10 11 12 | # Time: O(nlogn) # Space: O(n) # Sorting and reoder solution. (92ms) class Solution( object ): def wiggleSort( self , nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ nums.sort() med = ( len (nums) - 1 ) / 2 nums[:: 2 ], nums[ 1 :: 2 ] = nums[med:: - 1 ], nums[:med: - 1 ] |
Python:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | # Time: O(n) ~ O(n^2) # Space: O(1) # Tri Partition (aka Dutch National Flag Problem) with virtual index solution. (TLE) from random import randint class Solution2( object ): def wiggleSort( self , nums): """ :type nums: List[int] :rtype: void Do not return anything, modify nums in-place instead. """ def findKthLargest(nums, k): left, right = 0 , len (nums) - 1 while left < = right: pivot_idx = randint(left, right) new_pivot_idx = partitionAroundPivot(left, right, pivot_idx, nums) if new_pivot_idx = = k - 1 : return nums[new_pivot_idx] elif new_pivot_idx > k - 1 : right = new_pivot_idx - 1 else : # new_pivot_idx < k - 1. left = new_pivot_idx + 1 def partitionAroundPivot(left, right, pivot_idx, nums): pivot_value = nums[pivot_idx] new_pivot_idx = left nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx] for i in xrange (left, right): if nums[i] > pivot_value: nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i] new_pivot_idx + = 1 nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right] return new_pivot_idx def reversedTriPartitionWithVI(nums, val): def idx(i, N): return ( 1 + 2 * (i)) % N N = len (nums) / 2 * 2 + 1 i, j, n = 0 , 0 , len (nums) - 1 while j < = n: if nums[idx(j, N)] > val: nums[idx(i, N)], nums[idx(j, N)] = nums[idx(j, N)], nums[idx(i, N)] i + = 1 j + = 1 elif nums[idx(j, N)] < val: nums[idx(j, N)], nums[idx(n, N)] = nums[idx(n, N)], nums[idx(j, N)] n - = 1 else : j + = 1 mid = ( len (nums) - 1 ) / 2 findKthLargest(nums, mid + 1 ) reversedTriPartitionWithVI(nums, nums[mid]) |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 | // O(n) space class Solution { public : void wiggleSort(vector< int >& nums) { vector< int > tmp = nums; int n = nums.size(), k = (n + 1) / 2, j = n; sort(tmp.begin(), tmp.end()); for ( int i = 0; i < n; ++i) { nums[i] = i & 1 ? tmp[--j] : tmp[--k]; } } }; |
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // O(1) space class Solution { public : void wiggleSort(vector< int >& nums) { #define A(i) nums[(1 + 2 * i) % (n | 1)] int n = nums.size(), i = 0, j = 0, k = n - 1; auto midptr = nums.begin() + n / 2; nth_element(nums.begin(), midptr, nums.end()); int mid = *midptr; while (j <= k) { if (A(j) > mid) swap(A(i++), A(j++)); else if (A(j) < mid) swap(A(j), A(k--)); else ++j; } } }; |
类似题目:
[LeetCode] 280. Wiggle Sort 摆动排序
[LeetCode] 75. Sort Colors 颜色排序
All LeetCode Questions List 题目汇总
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架