「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」。
题目
给你一个整数数组 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 * 1040 <= nums[i] <= 5000- 题目数据保证,对于给定的输入
nums,总能产生满足题目要求的结果
进阶: 你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?
思考
我们不难发现,本题与 摆动序列 类似。本题难度中等。在本题中,我们需要对给出的整数数组进行操作,使得返回的数组满足一小一大交替分布的特点,这也就是摆动排序的过程。
由于数组是一小一大交替分布的,那么我们可以将原数组进行排序,然后分为两个子数组,再逐一各自取出数组的元素,将两个数组进行穿插分布。考虑到数组元素可能有相同数值,比如对于数组[1, 2, 2, 3],返回结果仍为[1, 2, 2, 3],我们可以将子数组反序后再穿插分布。
解答
方法一:排序
var wiggleSort = function(nums) {
// 排序
nums.sort((a, b) => a - b)
// 分组、反序
let arr1 = nums.slice(0, Math.ceil(nums.length / 2)).reverse()
let arr2 = nums.slice(Math.ceil(nums.length / 2)).reverse()
// 原地修改nums数组
for (let i = 0; i < nums.length; i++) {
nums[i] = i % 2 === 0 ? arr1.shift() : arr2.shift()
}
return nums
}
// 执行用时:932 ms, 在所有 JavaScript 提交中击败了5.05%的用户
// 内存消耗:45.9 MB, 在所有 JavaScript 提交中击败了17.17%的用户
优化
var wiggleSort = function(nums) {
let tmp = nums.slice().sort((a, b) => a - b)
// 获取中位数索引mid
let r = nums.length, mid = Math.floor((nums.length + 1) / 2)
for(l = 0; l < nums.length; l++) {
nums[l] = l % 2 === 0 ? tmp[--mid] : tmp[--r]
}
return nums
}
// 执行用时:84 ms, 在所有 JavaScript 提交中击败了95.96%的用户
// 内存消耗:46.1 MB, 在所有 JavaScript 提交中击败了9.09%的用户
复杂度分析
- 时间复杂度:
O(NlogN),需要对数组进行排序。 - 空间复杂度:
O(N),存储数组。