且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

[LintCode] Wiggle Sort II 扭动排序之二

更新时间:2022-09-16 19:24:50

Given an unsorted array nums, reorder it such that

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

You may assume all input has valid answer.

Example
Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].

Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].

Challenge 
Can you do it in O(n) time and/or in-place with O(1) extra space?

LeetCode上的原题,请参见我之前的博客Wiggle Sort II

解法一:

class Solution {
public:
    /**
     * @param nums a list of integer
     * @return void
     */  
    void wiggleSort(vector<int>& nums) {
        vector<int> t = nums;
        int n = nums.size(), k = (n + 1) / 2, j = n;
        sort(t.begin(), t.end());
        for (int i = 0; i < n; ++i) {
            nums[i] = i & 1 ? t[--j] : t[--k];
        }
    }
};

解法二:

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

解法三:

class Solution {
public:
    /**
     * @param nums a list of integer
     * @return void
     */  
    void wiggleSort(vector<int>& nums) {
        #define A(i) nums[(1 + i * 2) % (n | 1)]
        int n = nums.size(), i = 0, j = 0, k = n - 1;
        int mid = partition(nums, 0, n - 1, n / 2);
        while (j <= k) {
            if (A(j) > mid) swap(A(i++), A(j++));
            else if (A(j) < mid) swap(A(j), A(k--));
            else ++j;
        }
    }
    int partition(vector<int> nums, int l, int r, int rank) {
        int left = l, right = r, pivot = nums[left];
        while (left < right) {
            while (left < right && nums[right] >= pivot) --right;
            nums[left] = nums[right];
            while (left < right && nums[left] <= pivot) ++left;
            nums[right] = nums[left];
        }
        if (left - l == rank) return pivot;
        else if (left - l < rank) return partition(nums, left + 1, r, rank - (left - l + 1));
        else return partition(nums, l, right - 1, rank);
    }
};

 本文转自博客园Grandyang的博客,原文链接:扭动排序之二[LintCode] Wiggle Sort II ,如需转载请自行联系原博主。