324. Wiggle Sort II


Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]…

Example 1:

Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].
Example 2:

Input: nums = [1, 3, 2, 2, 3, 1]
Output: One possible answer is [2, 3, 1, 3, 1, 2].

Note:
You may assume all input has valid answer.

Follow Up:

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

方法1: sort

思路:

先对数组排序,然后找到中位数,用两个pt 从前半段和后半段的末尾交替取数。为什么要这么做呢?对于非重复序列来讲,这只是众多选择中的一种。从下面代码中的例子来看,wiggle1是用这种方法,由两个交替单调递减序列构成。wiggle2由一个单减一个单增构成,这两种都满足题意。但是注意到我们的目的只是让每个数字比它临近的两个数大/小就行了,这里大数被“浪费”在了波动末尾的较小值上。而如果数组中有重复数字,这个方法可能造成前面的波动不够大。比如第二个例子。由于这道题保证了一定有解,那么最保险的做法必须是用大数和大数去比较,才有可能找到解。

Complexity

Time complexity: O(nlogn)
Space complexity: O(n)

// nums    [1, 2, 3, 4, 5, 6 ,7, 8, 9, 10 ]
// wiggle1 [5, 10, 4, 9, 3, 8, 2, 7, 1, 6]
// wiggle2 [5, 6, 4, 7, 2, 8, 3, 9, 2, 10, 1]

// nums    [1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3]
// wiggle1 [2, 3, 2, 3, 2, 3, 2, 3, 2, 2, 1, 2, 1, 2]
// wiggle2 [2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 3, 1, 3, 1]
class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        if (nums.empty()) return;
        int n = nums.size();
        vector<int> tmp = nums;
        sort(tmp.begin(), tmp.end());
        
        int pt1 = (n + 1) / 2, pt2 = n;
        for (int i = 0; i < n; i ++){
            nums[i] = i & 1 ? tmp[--pt2] : tmp[--pt1];
        }
        return;
    }
};

方法2: partition

思路:

discussion:https://leetcode.com/problems/wiggle-sort-ii/discuss/77677/O(n)%2BO(1)-after-median-Virtual-Indexing

class Solution {
public:
    /**
     * @param nums a list of integer
     * @return void
     */  
    void wiggleSort(vector<int>& nums) {
        // Write your code 
        // Find a median.
        if (nums.empty()) return;
        int n = nums.size();
        
        auto midptr = nums.begin() + n / 2;
        nth_element(nums.begin(), midptr, nums.end());
        int mid = *midptr;
        
        // Index-rewiring.
        //#define A(i) nums[(1+2*(i)) % (n|1)]

        // 3-way-partition-to-wiggly in O(n) time with O(1) space.
        int i = 0, j = 0, k = n - 1;
        if (A(i) > mid){
            swap(A(i++), A(j++));
        }
        else if (A(i) < mid){
            swap(A(j), A(k--));
        }
        else{
            j++;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值