LintCode 508: Wiggle Sort

LintCode 508: Wiggle Sort

题目描述

给你一个没有排序的数组,请将原数组就地重新排列满足如下性质

nums[0] <= nums[1] >= nums[2] <= nums[3]....

Thu Feb 23 2017

思路

这道题看起来好像无从下手,但其实思路很简单,方法也有很多种。

第一种方法

先将数组排序,然后将第二个、第三个数交换,第四个、第五个数交换...即可。时间复杂度是\(O(nlogn)\).

第二种方法

第二种方法先找出数字们的中位数,然后将大于中位数的数放在奇数位上,小于中位数的数放在偶数位上。

求中位数算法的时间复杂度可以做到\(O(n)\),即利用快排的思想,对于每一次划分出来的partition,下一次只递归中位数所在的那一半数组。虽然在最坏情况下时间复杂度是\(O(n^2)\),但是平均情况是\(O(n)\).

找到中位数后,由于题目要求只能在原数组上原地排序,不能借用新数组,所以应该还是要利用快排的思想,在数组中分别找到在奇数位但比中位数小的数,以及在偶数位但比中位数大的数,然后两者交换。这个方法在存在很多与中位数相等的数的时候不太好用,待使用更好的解决方案。

第三种方法

上面想了那么多,最后发现原来题目还可以更简单一点。

其实只需要从第1个数开始向后遍历,每次检查当前数与前一个数是否满足大小关系:在奇数位的数要大于偶数位的数。

代码

// 只放第三种方法
void wiggleSort(vector<int>& nums) 
{
    for(int i = 1; i < nums.size(); ++i)
        if((i % 2 == 1 && nums[i] < nums[i - 1]) 
        || (i % 2 == 0 && nums[i] > nums[i - 1]))
            swap(nums[i - 1], nums[i]);
}
posted @ 2017-02-23 15:16  GenkunAbe  阅读(279)  评论(0编辑  收藏  举报