分治 快速选择 排序 数组 贪心
题目描述 给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。
你可以假设所有输入数组都可以得到满足题目要求的结果。
示例 1:
输入: nums = [1,5,1,1,6,4]
输出: [1,6,1,5,1,4]
解释: [1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。
示例 2:
输入: nums = [1,3,2,2,3,1]
输出: [2,3,1,3,1,2]
提示:
1 <= nums.length <= 5 * 104 0 <= nums[i] <= 5000 题目数据保证,对于给定的输入 nums ,总能产生满足题目要求的结果
进阶: 你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?
解法 方法一:排序 思考
要求 \(nums[0]<nums[1]>nums[2]<\cdots\) ,且原数组无此序。就地重排即可,不必稳定。
排序后从中位数向前取小的放偶数位、从末尾向前取大的放奇数位,可避免相邻相等。中位数与最大值反向填充,使相等元素被隔开。
Python3 Java C++ Go JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class Solution :
def wiggleSort ( 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 - 1
for k in range ( n ):
if k % 2 == 0 :
nums [ k ] = arr [ i ]
i -= 1
else :
nums [ k ] = arr [ j ]
j -= 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class Solution {
public void wiggleSort ( int [] nums ) {
int [] arr = nums . clone ();
Arrays . sort ( arr );
int n = nums . length ;
int i = ( n - 1 ) >> 1 , j = n - 1 ;
for ( int k = 0 ; k < n ; ++ k ) {
if ( k % 2 == 0 ) {
nums [ k ] = arr [ i --] ;
} else {
nums [ k ] = arr [ j --] ;
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 class Solution {
public :
void wiggleSort ( vector < int >& nums ) {
vector < int > arr = nums ;
sort ( arr . begin (), arr . end ());
int n = nums . size ();
int i = ( n - 1 ) >> 1 , j = n - 1 ;
for ( int k = 0 ; k < n ; ++ k ) {
if ( k % 2 == 0 )
nums [ k ] = arr [ i -- ];
else
nums [ k ] = arr [ j -- ];
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 func wiggleSort ( nums [] int ) {
n := len ( nums )
arr := make ([] int , n )
copy ( arr , nums )
sort . Ints ( arr )
i , j := ( n - 1 ) >> 1 , n - 1
for k := 0 ; k < n ; k ++ {
if k % 2 == 0 {
nums [ k ] = arr [ i ]
i --
} else {
nums [ k ] = arr [ j ]
j --
}
}
}
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 /**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var wiggleSort = function ( nums ) {
let bucket = new Array ( 5001 ). fill ( 0 );
for ( const v of nums ) {
bucket [ v ] ++ ;
}
const n = nums . length ;
let j = 5000 ;
for ( let i = 1 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) {
-- j ;
}
nums [ i ] = j ;
-- bucket [ j ];
}
for ( let i = 0 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) {
-- j ;
}
nums [ i ] = j ;
-- bucket [ j ];
}
};
方法二:桶排序 思考
方法一需要 \(O(n\log n)\) 排序与额外数组。值域为 \([0,5000]\) ,用桶计数后从大到小先填奇数位再填偶数位,同样把大数放峰、小数放谷,时间线性。
Python3 Java C++ Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 class Solution :
def wiggleSort ( self , nums : List [ int ]) -> None :
"""
Do not return anything, modify nums in-place instead.
"""
bucket = [ 0 ] * 5001
for v in nums :
bucket [ v ] += 1
n = len ( nums )
j = 5000
for i in range ( 1 , n , 2 ):
while bucket [ j ] == 0 :
j -= 1
nums [ i ] = j
bucket [ j ] -= 1
for i in range ( 0 , n , 2 ):
while bucket [ j ] == 0 :
j -= 1
nums [ i ] = j
bucket [ j ] -= 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 class Solution {
public void wiggleSort ( int [] nums ) {
int [] bucket = new int [ 5001 ] ;
for ( int v : nums ) {
++ bucket [ v ] ;
}
int n = nums . length ;
int j = 5000 ;
for ( int i = 1 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) {
-- j ;
}
nums [ i ] = j ;
-- bucket [ j ] ;
}
for ( int i = 0 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) {
-- j ;
}
nums [ i ] = j ;
-- bucket [ j ] ;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 class Solution {
public :
void wiggleSort ( vector < int >& nums ) {
vector < int > bucket ( 5001 );
for ( int & v : nums ) ++ bucket [ v ];
int n = nums . size ();
int j = 5000 ;
for ( int i = 1 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) -- j ;
nums [ i ] = j ;
-- bucket [ j ];
}
for ( int i = 0 ; i < n ; i += 2 ) {
while ( bucket [ j ] == 0 ) -- j ;
nums [ i ] = j ;
-- bucket [ j ];
}
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 func wiggleSort ( nums [] int ) {
bucket := make ([] int , 5001 )
for _ , v := range nums {
bucket [ v ] ++
}
n , j := len ( nums ), 5000
for i := 1 ; i < n ; i += 2 {
for bucket [ j ] == 0 {
j --
}
nums [ i ] = j
bucket [ j ] --
}
for i := 0 ; i < n ; i += 2 {
for bucket [ j ] == 0 {
j --
}
nums [ i ] = j
bucket [ j ] --
}
}
GitHub