324. Wiggle Sort II

37 篇文章 0 订阅

这几天做的题有点多,所以,博客写的有点简单。

这道题是要大小数叉开,整个序列将会成为小大间隔开来,如果是我们正常情况下,肯定是选择一个中位数,然后将数组对半分开,小数放在偶数位上,大数放在奇数位上,但这就要求空间复杂度和时间复杂度都要是O(n),而题目要求不能有额外的空间消耗,因此,需要在空间复杂度上来考虑。

我们的目的是将小数放在偶数位上,大数放在奇数位上,要做到这一点我们需要两步骤,首先要确定哪些数是小数,哪些数是大数,其次是要将这些数都放在对应的位置上。

要想知道哪些数是大数,哪些数是小数,因为无法通过额外的空间进行记录,所以一种比较好的办法是找到他们的中位数,这样,在使用的时候,通过让数和中位数进行对比,就可以知道该数是小还是大。

拿出一个数和中位数进行比较,然后向指定位置上搬运,这种操作好像在二分法中用的很多,但是,不同的是,二分法中,是将数往左边和右边放,而此时我们是打算将数往奇偶位上移动,所以,要区分索引的奇偶性。而这一步我们可以借用二分法中的大小指针法去做,举个例子,我们可以把二分法中的小指针映射成奇数位,把二分法张的大指针映射成偶数位,要让一个数变成奇数,最好的办法就是: num*2+1。而让一个奇数变成偶数的方法就是:对一个奇数取余。num%奇数。

基于以上的思想,参考大神的代码,AC代码如下:

class Solution {
public:
    
    void wiggleSort(vector<int>& nums) {
        int numSize = nums.size();
        if (numSize < 2) {
            return ;
        }
        #define A(i) nums[(2*i+1)%(numSize|1)] 
        int midPos = 0;
        nth_element(nums.begin(), nums.begin()+numSize/2, nums.end());
        int mid = nums[numSize/2];
        
        int i=0, j=0, k=numSize-1;
        
        while (j <= k) {
            if (A(j) > mid) {
                swap (A(i++), A(j++));
            } else if (A(j) < mid) {
                swap (A(j), A(k--));
            } else {
                ++j;
            }
        }
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值