摆动排序 II · Wiggle Sort II

该代码段展示了一个C++实现的wiggleSort方法,首先使用partition函数找到数组中第n/2位置的元素,然后根据数组长度的奇偶性选择首尾指针进行交替交换,以达到wiggle排序的效果。同时,包含了kthLargestElement函数用于找到第k大的元素,整个过程涉及快速选择算法。
摘要由CSDN通过智能技术生成

链接:

题解:

1.先用partition函数,求得n/2的位置的排序

2.然后选取首尾指针(奇数选择1和length-1,偶数选择为1和length-2),进行swap交换

3.每次首指针每次+2,尾指针每次-2

九章算法 - 帮助更多程序员找到好工作,硅谷顶尖IT企业工程师实时在线授课为你传授面试技巧

 

这段代码没有通过

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: nothing
     */
    void wiggleSort(vector<int> &nums) {
        // write your code here
        if (nums.size() <= 1) {
            return;
        }
        int len = nums.size();
        kthLargestElement(len/2, nums);
        if (len % 2 == 0) {
            int left = 1;
            int right = nums.size()-2;
            while (left < right) {
                swap(nums[left], nums[right]);
                left += 2;
                right -= 2;
            }
        } else {
            int left = 1;
            int right = nums.size() - 1;
            while (left < right) {
                swap(nums[left], nums[right]);
                left += 2;
                right -= 2;
            }
        }
    }

private:
    int kthLargestElement(int k, vector<int> &nums) {
        cout << "k=" << k << endl;
        // write your code here
        if (nums.size() <= 0) {
            return 0;
        }
        int left = 0;
        int right = nums.size()-1;
        int mid = partition(nums, left, right);
        //cout << "mid=" << mid << endl;
        while (mid != k-1) {
            //cout << "mid=====" << mid << endl;
            if (mid > k) {
                right = mid;
            } else {
                left = mid;
            }
            mid = partition(nums, left, right);
        }
        return nums[mid];
    }
   
    int partition(std::vector<int>& nums, int left, int right) {
        int index = random() % (right-left+1);
        swap(nums[right], nums[left+index]);
        int nSmall = left - 1;
        for (; left < right; ++left) {
            if (nums[left] <= nums[right]) {
                ++nSmall;
                swap(nums[left], nums[nSmall]);
            }
        }
        ++nSmall;
        swap(nums[right], nums[nSmall]);
        cout << nSmall << " val=" << nums[nSmall] << endl;  
        return nSmall;
    }
};
class Solution {
public:
    // O(n)时间复杂度,O(1)空间
    void wiggleSort(vector<int>& nums) {

        if (nums.size() <= 0) {
            return;
        }
        /*for (auto num : nums) {
            cout << num << " ";
        }
        cout << endl;*/
        int len = nums.size();
        // 求得第几大的位置
        // 0 1 2 3/2 = 1,假设3个数字,就是求得第2大的数字位置
        // 0, 1, 2, 3  4/2 = 2,假设4个个数字,就是求得第3大的数字位置
        partition(nums, 0, len-1, len/2+1);
        /*for (auto num : nums) {
            cout << num << "  yyy ";
        }*/
        int left = 0;
        int right = len-1;
        // 如果是奇数的情况,把右边的数字排出下
        if (len % 2) {
            --right;
        }
        // 原地交换
        while (left < right) {
            // 交换
            swap(nums[left], nums[right]);
            // 空出一个位置不需要交换
            left += 2;
            right -= 2;
        }
        /*for (auto num : nums) {
            cout << num << " ";
        }
        cout << endl;
        std::vector<int> result;
        result.reserve(len);
        int left = 0;
        int right = len-1;
        while (left <= right) {
            if (left == right) {
                result.push_back(nums[left]);
            } else {
                result.push_back(nums[left]);
                result.push_back(nums[right]);
            }
            ++left;
            --right;
        }
        nums = std::move(result);*/
    }
private:

    int partition(std::vector<int>& nums, int start, int end, int k) {
        if (start >= end) {
            return start;
        }
        int val = nums[start+(end-start)/2];
        int l = start;
        int r = end;
        //cout << l << " " << val << " " << r << endl;
        while (l <= r) {
            while (l <= r && nums[l] < val) {
                //cout << "nums" << endl;
                ++l;
            }
            while (l <= r && nums[r] > val) {
                //cout << "nums" << endl;
                --r;
            }
            if (l <= r) {
                swap(nums[l], nums[r]);
                //cout << "left :" << l << " " << nums[l] << " right:" << r << " " << nums[r] << endl;
                ++l;
                --r;
            }
        }
        if (start + k - 1 <= r) {
            return partition(nums, start, r, k);
        }
        if (start + k - 1 >= l) {
            return partition(nums, l, end, k - (l - start));
        }
        return r + 1;
    }
};

. - 力扣(LeetCode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值