leetcode题解:324. Wiggle Sort II

本文详细介绍了如何解决LeetCode上的324题——摆动排序II。首先找到数组的中位数,然后根据奇偶位置分别放置大于和小于中位数的元素。对于有多个中位数的情况,先跳过中位数,最后再处理。AC代码给出了解决方案的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://leetcode.com/problems/wiggle-sort-ii/

1. 解题思路

参考自https://leetcode.com/problems/wiggle-sort-ii/discuss/77682/Step-by-step-explanation-of-index-mapping-in-Java

先找出数组的中位数,然后for循环遍历数组,大于中位数的放在奇数index上,小于中位数的放在偶数index上。

若数组长度为4,按照:1 3 0 2的顺序遍历

若数组长度为5,按照:1 3 5 0 2的顺序遍历

总结来说就是按照(2i+1)%(n|1)的顺序遍历数组。

注意需要处理多个中位数的情况,此时不能保证中位数应该放在偶数index还是奇数index上,处理方法是先不管直接跳过,放置完所有非中位数的数,中位数怎么放置都可以。

2. AC代码

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int left=0, right=nums.size()-1;
        // k = nums.size() - k;
        int mid, i, j;
        while(left<right){
            if(right-left==1){
                if(nums[left]>nums[right]) swap(nums[left], nums[right]);
                if(left==k) return nums[left];
                else return nums[right];
            }
            mid = (left+right)/2;
            median(nums, left, right, mid);
            i = left;
            j = right-1;
            while(i<j){
                while(nums[++i]<nums[right-1]) {}
                while(nums[--j]>nums[right-1]) {}
                if(i<j) swap(nums[i], nums[j]);
            }
            swap(nums[right-1], nums[i]);
            if(i==k) return nums[i];
            else if(k<i) right = i-1;
            else left = i+1;
        }
        return nums[left];
    }
    void median(vector<int>& nums, int left, int right, int mid){
        if(nums[left]>nums[mid]) swap(nums[left], nums[mid]);
        if(nums[left]>nums[right]) swap(nums[left], nums[right]);
        if(nums[mid]>nums[right]) swap(nums[mid], nums[right]);
        swap(nums[mid], nums[right-1]);
    }
    int new_index(int i, int n){
        return (2*i+1) % (n|1);
    }
    void wiggleSort(vector<int>& nums) {
        int n = nums.size();
        int mid = findKthLargest(nums, (n-1)/2);
        int left = 0, right = n-1, i=0;
        while(i<=right){
            if(nums[new_index(i, n)]>mid){
                swap(nums[new_index(i, n)], nums[new_index(left, n)]);
                left++;
                i++;
            }
            else if(nums[new_index(i, n)]<mid){
                swap(nums[new_index(i, n)], nums[new_index(right, n)]);
                right--;
            }
            else i++; //这一步非常重要,跳过中位数
        }
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值