324 摆动排序 II

题目描述:
给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。

示例 1:
输入: nums = [1, 5, 1, 1, 6, 4]
输出: 一个可能的答案是 [1, 4, 1, 5, 1, 6]

示例 2:
输入: nums = [1, 3, 2, 2, 3, 1]
输出: 一个可能的答案是 [2, 3, 1, 3, 1, 2]

说明:
你可以假设所有输入都会得到有效的结果。
进阶:
你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?

方法1:
主要思路:
(1)将原来的数组进行排序;
(2)然后将排序后的数组分成前后两个部分,为了能够避免中间重复元素的影响,前后两个部分都从后向前遍历,依次放入数组中;
(3)注意若是奇数个元素,则前半部分可以多分得一个元素进行排序;

class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        vector<int> tmp=nums;
        sort(tmp.begin(),tmp.end());//对数组进行排序
        
        //将数组分成前后两部分
        int mid=tmp.size()/2;
        if(tmp.size()%2==0){//若数组元素的个数是偶数个
            --mid;
        }
        //将前后两部分元素依次放入到数组中
        int left=mid;
        int right=nums.size()-1;
        int pos=0;
        while(left>=0){
            nums[pos++]=tmp[left--];
            if(right>mid){//避免越界多放
                nums[pos++]=tmp[right--];
            } 
        }
        return;
    }

方法2:
主要思路:
(1)从方法1中可以看出,分割前后两部分,重要的是找出中间元素,再保证前半部分的元素小于中间元素,后半部分的元素大于中间元素,而其内部顺序不重要;
(2)故可以先找出中间元素,然后使用中间元素将数组分成两部分,再进行赋值操作;

class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        vector<int> tmp=nums;//辅助数组
        int mid=nums.size()/2;
        nth_element(tmp.begin(),tmp.begin()+mid,tmp.end());//找出中间元素
		//将数组元素分成前后两个部分
        int left=0;
        int pos=0;
        int right=tmp.size()-1;
        while(pos<right){
            if(tmp[pos]>tmp[mid]){
                swap(tmp[pos],tmp[right--]);
            }
            else {
                if(tmp[pos]<tmp[mid]){
                    swap(tmp[pos],tmp[left++]);
                }
                ++pos;
            }
        }
        if(tmp.size()%2==0){//偶数的情形
            --mid;
        }
		//将数组的元素进行赋值
        left=mid;
        right=tmp.size()-1;
        pos=0;
        while(left>=0){
            nums[pos++]=tmp[left--];
            if(right>mid){
                nums[pos++]=tmp[right--];
            }
        }
        return ;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值