持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
一、题目描述:
给你一个整数数组 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) 额外空间来实现吗?
来源:力扣(LeetCode) 链接:leetcode.cn/problems/wi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、思路分析:
首先,必须全局地看,如果贪心,可能会造成无结果.如3,4,2,2。 结果数组“升-降-升”的规律,其中,升的位置为第2i,降的位置是第2i+1,且nums[2i]<nums[2i+1],因此,可以考虑把nums分成两部分:一部分较小,一部分较大,分别用于填充升和降的部分。令n=nums.size(),那么小的部分元素数目为cnt = (n+1)/2;那么元素值较大的部分数目就为n-cnt。然后,使用双指针法,交叉地选取元素并填充到nums中就可以了。 为了分成两部分,可以考虑使用桶,桶大小为5001。遍历一遍nums,将每个元素的个数计数。然后,找到第cnt个元素last,这是小的部分的最后一个。 对于样例[4,5,5,6],可以分成较小部分[4,5]和较大部分[5,6],如果在填充nums时,都从左往右取,那么会得到结果[4,5,5,6],但是这是错误的。正确的应该是[5,6,4,5],因此,可以考虑从右往左取。但是为什么方向要一致呢?这是为了最大化差异,防止出现相同的元素被同时选取
三、AC 代码:
class Solution {
public void wiggleSort(int[] nums) {
Arrays.sort(nums);
int[] tempArray = nums.clone();
int avg = nums.length / 2;
int tempNum = 1;
for (int i = 1; i <= avg; i++) {
nums[tempNum] = tempArray[tempArray.length - i];
tempNum = tempNum + 2;
}
int avg2 = nums.length - avg;
tempNum = 0;
for (int i = 1; i <= avg2; i++) {
nums[tempNum] = tempArray[tempArray.length - i - avg];
tempNum = tempNum + 2;
}
}
}
四、总结:
掘友们,解题不易,留下个赞或评论再走吧!谢啦~ 💐
希望对你有帮助,期待您找到心意的工作和满意的offer
期待下次再见~
🌇 点赞 👍 收藏 ⭐留言 📝 一键三连 ~关注Jam,从你我做起!