在一个整数数组中,“峰”是大于或等于相邻整数的元素,相应地,“谷”是小于或等于相邻整数的元素。例如,在数组{5, 8, 4, 2, 3, 4, 6}中,{8, 6}是峰, {5, 2}是谷。现在给定一个整数数组,将该数组按峰与谷的交替顺序排序。
示例:
输入: [5, 3, 1, 2, 3]
输出: [5, 1, 3, 2, 3]
提示:
nums.length <= 10000
分析:
方法1:先排序再交替
最简单粗暴的方式就是先进行排序,因为排序后的数组是非递减的,所以只要每两个交换一下,就能得到峰谷的形式。
时间复杂度:O(n*log n) 内置排序函数一半为快速排序,时间复杂度为 n * log n
空间复杂度:O(n*log n)
class Solution {
public void wiggleSort(int[] nums) {
//排序
Arrays.sort(nums);
//两两交换
for(int i = 2; i < nums.length; i += 2){
int temp = nums[i-1];
nums[i-1] = nums[i];
nums[i] = temp;
}
}
}
方法2:贪心+冒泡
既然是求峰谷交替的顺序,我们可以定义偶数位置为峰,奇数位置为谷,如果峰小于前个谷,交换峰和谷的值,如果谷大于前个峰,交换。
证明:定义 a,b,c,d 三个数代表谷峰谷峰的位置,如果 b < a,那么 a b 交换,而 b c 交换的条件就是 c > a,但 b < a,那么 c 一定大于 b,谷峰反过来同理,所以无论前面是否交换,都不影响后面的交换。
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public void wiggleSort(int[] nums) {
//两两交换
for(int i = 1; i < nums.length; ++i){
//峰
if(i % 2 == 0){
//小于谷
if(nums[i] < nums[i-1]){
swap(nums, i, i-1);
}
}
//谷
else{
//大于峰
if(nums[i] > nums[i-1]){
swap(nums, i, i-1);
}
}
}
}
//交换
public void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/peaks-and-valleys-lcci