要求:小大小大…。时间O(n)或者空间O(1) 思路: 法一:桶代替排序
class Solution {
public:
void wiggleSort(vector<int>& nums) {
int bucket[5001]={0};
for(int num:nums)bucket[num]++;
int len=nums.size();
int small,big;
if((len&1)==1){
small=len-1;
big=len-2;
}else{
small=len-2;
big=len-1;
}
int j=5000;
for(int i=1;i<=big;i+=2){
while (bucket[j]==0)j--;
nums[i]=j;
bucket[j]--;
}
for(int i=0;i<=small;i+=2){
while (bucket[j]==0)j--;
nums[i]=j;
bucket[j]--;
}
}
};
法二:先快排找中间的数,然后跟中间的数相同的聚拢到中间,这样数组分为三部分,然后按中间右边的顺序写回开头
class Solution {
private:
int p,size;
public:
void quick_pick(vector<int>& nums,int left,int right){
int l=left,r=right;
while(left<right){
while(left<right&&nums[right]>=nums[left])right--;
swap(nums[left],nums[right]);
while(left<right&&nums[left]<=nums[right])left++;
swap(nums[left],nums[right]);
}
if(left==p)return;
else if(left>p)quick_pick(nums,l,left-1);
else quick_pick(nums,left+1,r);
}
void wiggleSort(vector<int>& nums) {
size=nums.size();
if(size<2)return;
p=(nums.size()+1)/2;
vector<int> helper=nums;
quick_pick(helper,0,size-1);
int left=p-1,right=p+1;
for(int i=p-1;i>=0;i--){
if(helper[i]==helper[p]){
swap(helper[i],helper[left]);
left--;
}
}
for(int i=p+1;i<size;i++){
if(helper[i]==helper[p]){
swap(helper[i],helper[right]);
right++;
}
}
int l=p-1,r=size-1,i=0;
while(i<size){
nums[i++]=helper[l--];
if(i<size)nums[i++]=helper[r--];
}
}
};
|