摆动排序 II
难度:
标签:
题目描述
给你一个整数数组 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) 额外空间来实现吗?
代码结果
运行时间: 33 ms, 内存: 17.4 MB
/*
* 思路:
* 利用Java Stream对数组进行排序,然后按照较小部分放在偶数位置,较大部分放在奇数位置来生成新的数组。
*/
import java.util.*;
import java.util.stream.IntStream;
public class WiggleSortStream {
public void wiggleSort(int[] nums) {
int n = nums.length;
int[] sorted = IntStream.of(nums).sorted().toArray();
int mid = (n + 1) / 2;
int[] temp = new int[n];
for (int i = 0; i < mid; i++) {
temp[i * 2] = sorted[mid - i - 1];
}
for (int i = mid; i < n; i++) {
temp[(i - mid) * 2 + 1] = sorted[n - i - 1];
}
System.arraycopy(temp, 0, nums, 0, n);
}
}
解释
方法:
该题解的思路是先将原数组 nums 排序,然后从排序后数组的中间位置和末尾位置交替取元素放入原数组。通过这种方式,可以使得相邻元素尽量不相等,从而满足摆动排序的要求。
时间复杂度:
O(nlogn)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在将数组排序之后选择从中间和末尾位置交替取值的方式来实现摆动排序?
▷🦆
在题解中提到的方法中,如果数组的长度是奇数,中间位置的元素处理方式是否有所不同?
▷🦆
题解使用了额外的数组来存储排序后的结果,这是否违背了原地修改数组的要求?如果是,有没有可能实现真正的原地修改?
▷🦆
在使用双指针方法中,如何确保每次从中间位置和末尾取出的元素能满足摆动排序的要求,特别是在遇到重复元素时?
▷相关问题
颜色分类
给定一个包含红色、白色和蓝色、共 n
个元素的数组 nums
,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0
、 1
和 2
分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
示例 1:
输入:nums = [2,0,2,1,1,0] 输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1] 输出:[0,1,2]
提示:
n == nums.length
1 <= n <= 300
nums[i]
为0
、1
或2
进阶:
- 你能想出一个仅使用常数空间的一趟扫描算法吗?