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?

280. Wiggle Sort 的变形,这题nums[0] < nums[1] > nums[2] < nums[3]....里面没有等号。

解法1:先对数组进行排序, 然后从左往右奇数索引位置放大于中位数的数, 然后从右往左在偶数索引位置放小于中位数的数, 剩下的位置都放中位数. 其T: O(nlog(n)), S: O(n).

解法2:利用quickSelect算法,从未经排序的数组nums中选出中位数mid,以中位数mid为界,将大于mid的元素排列在ix的较小部分,而将小于mid的元素排列在ix的较大部分。T: O(n), S: O(1)

解法3:three-way partitioning,variant of 75. Sort Colors

Java:

public void wiggleSort(int[] nums) {
int median = findKthLargest(nums, (nums.length + 1) / 2);
int n = nums.length; int left = 0, i = 0, right = n - 1; while (i <= right) { if (nums[newIndex(i,n)] > median) {
swap(nums, newIndex(left++,n), newIndex(i++,n));
}
else if (nums[newIndex(i,n)] < median) {
swap(nums, newIndex(right--,n), newIndex(i,n));
}
else {
i++;
}
} } private int newIndex(int index, int n) {
return (1 + 2*index) % (n | 1);
}

Java:

void wiggleSort(vector<int>& nums) {
int n = nums.size(); // Find a median.
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;
while (j <= k) {
if (A(j) > mid)
swap(A(i++), A(j++));
else if (A(j) < mid)
swap(A(j), A(k--));
else
j++;
}
}

Java:

public class Solution {
public void wiggleSort(int[] nums) {
int medium = findMedium(nums, 0, nums.length - 1, (nums.length + 1) >> 1);
int s = 0, t = nums.length - 1 , mid_index = (nums.length + 1) >> 1;
int[] temp = new int[nums.length];
for (int i = 0; i < nums.length; i++) {
if (nums[i] < medium)
temp[s++] = nums[i];
else if (nums[i] > medium)
temp[t--] = nums[i];
} while (s < mid_index) temp[s++] = medium;
while (t >= mid_index) temp[t--] = medium; t = nums.length;
for (int i = 0; i < nums.length; i++)
nums[i] = (i & 1) == 0 ? temp[--s] : temp[--t];
} private int findMedium(int[] nums, int L, int R, int k) {
if (L >= R) return nums[R];
int i = partition(nums, L, R);
int cnt = i - L + 1;
if (cnt == k) return nums[i];
return cnt > k ? findMedium(nums, L, i - 1, k) : findMedium(nums, i + 1, R, k - cnt);
} private int partition(int[] nums, int L, int R) {
int val = nums[L];
int i = L, j = R + 1;
while (true) {
while (++i < R && nums[i] < val) ;
while (--j > L && nums[j] > val) ;
if (i >= j) break;
swap(nums, i, j);
}
swap(nums, L, j);
return j;
} private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}  

Python:

# Time:  O(nlogn)
# Space: O(n)
# Sorting and reoder solution. (92ms)
class Solution(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
nums.sort()
med = (len(nums) - 1) / 2
nums[::2], nums[1::2] = nums[med::-1], nums[:med:-1]  

Python:

# Time:  O(n) ~ O(n^2)
# Space: O(1)
# Tri Partition (aka Dutch National Flag Problem) with virtual index solution. (TLE)
from random import randint
class Solution2(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
def findKthLargest(nums, k):
left, right = 0, len(nums) - 1
while left <= right:
pivot_idx = randint(left, right)
new_pivot_idx = partitionAroundPivot(left, right, pivot_idx, nums)
if new_pivot_idx == k - 1:
return nums[new_pivot_idx]
elif new_pivot_idx > k - 1:
right = new_pivot_idx - 1
else: # new_pivot_idx < k - 1.
left = new_pivot_idx + 1 def partitionAroundPivot(left, right, pivot_idx, nums):
pivot_value = nums[pivot_idx]
new_pivot_idx = left
nums[pivot_idx], nums[right] = nums[right], nums[pivot_idx]
for i in xrange(left, right):
if nums[i] > pivot_value:
nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i]
new_pivot_idx += 1
nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right]
return new_pivot_idx def reversedTriPartitionWithVI(nums, val):
def idx(i, N):
return (1 + 2 * (i)) % N N = len(nums) / 2 * 2 + 1
i, j, n = 0, 0, len(nums) - 1
while j <= n:
if nums[idx(j, N)] > val:
nums[idx(i, N)], nums[idx(j, N)] = nums[idx(j, N)], nums[idx(i, N)]
i += 1
j += 1
elif nums[idx(j, N)] < val:
nums[idx(j, N)], nums[idx(n, N)] = nums[idx(n, N)], nums[idx(j, N)]
n -= 1
else:
j += 1 mid = (len(nums) - 1) / 2
findKthLargest(nums, mid + 1)
reversedTriPartitionWithVI(nums, nums[mid])

C++:

// O(n) space
class Solution {
public:
void wiggleSort(vector<int>& nums) {
vector<int> tmp = nums;
int n = nums.size(), k = (n + 1) / 2, j = n;
sort(tmp.begin(), tmp.end());
for (int i = 0; i < n; ++i) {
nums[i] = i & 1 ? tmp[--j] : tmp[--k];
}
}
};  

C++:

// O(1) space
class Solution {
public:
void wiggleSort(vector<int>& nums) {
#define A(i) nums[(1 + 2 * i) % (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;
}
}
};

  

类似题目:

[LeetCode] 280. Wiggle Sort 摆动排序

[LeetCode] 75. Sort Colors 颜色排序

All LeetCode Questions List 题目汇总

[LeetCode] 324. Wiggle Sort II 摆动排序 II的更多相关文章

  1. LeetCode 280. Wiggle Sort (摆动排序)$

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  2. 324 Wiggle Sort II 摆动排序 II

    给定一个无序的数组nums,将它重新排列成nums[0] < nums[1] > nums[2] < nums[3]...的顺序.例子:(1) 给定nums = [1, 5, 1, ...

  3. leetcode 324 Wiggle Sort 2

    利用中位数的概念,中位数就是将一组数分成2等份(若为奇数,则中位数既不属于左也不属于右,所以是2等份),其一组数中任何一个元素都大于等于另一组数 那么我们是不是只要一左一右配合着插入,就保证了差值+- ...

  4. [LeetCode] 280. Wiggle Sort 摆动排序

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  5. leetcode 280.Wiggle Sort 、324. Wiggle Sort II

    Wiggle Sort: 注意:解法一是每次i增加2,题目不是保证3个3个的情况,而是整个数组都要满足要求. 解法一错误版本: 如果nums的长度是4,这种情况下nums[i+1]会越界.但是如果你用 ...

  6. Leetcode 324.摆动排序II

    摆动排序II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums ...

  7. Java实现 LeetCode 324 摆动排序 II

    324. 摆动排序 II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]- 的顺序. 示例 1: 输入: n ...

  8. [LeetCode] Wiggle Sort II 摆动排序

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

  9. [LeetCode] Wiggle Sort II 摆动排序之二

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

随机推荐

  1. LGOJP2051 [AHOI2009]中国象棋

    比较明显的计数dp.不知道为什么被打了状压的tag... 不难发现无论炮放在哪里其实是等价的,需要知道的只有这一列放了一个炮还是两个炮还是还没放,那么可以设\(f[i,j,k]\)表示第\(i\)行, ...

  2. JQuery系列(3) - 工具方法

    jQuery函数库提供了一个jQuery对象(简写为$),这个对象本身是一个构造函数,可以用来生成jQuery对象的实例.有了实例以后,就可以调用许多针对实例的方法,它们定义jQuery.protot ...

  3. LeetCode 1135. Connecting Cities With Minimum Cost

    原题链接在这里:https://leetcode.com/problems/connecting-cities-with-minimum-cost/ 题目: There are N cities nu ...

  4. 001_keil仿真

    (一)参考文献:STM32F4 MDK5软件仿真 error : no 'read' permission  (二)转载: 问题描述 CPU:STM32F407MDK5软件模拟提示没有读写权限,只能一 ...

  5. RookeyFrame bin 目录

    如果把bin目录删掉,重新生成的话,还需要加载很多东西哦,具体可以对比一下下载下来的文件

  6. CF1172E Nauuo and ODT

    CF1172E Nauuo and ODT 神仙题orz 要算所有路径的不同颜色之和,多次修改,每次修改后询问. 对每种颜色\(c\)计算多少条路径包含了这个颜色,不好算所以算多少条路径不包含这个颜色 ...

  7. 如何在Unity中开发Leap Motion桌面版(Non-VR)APP

    最近因需要,翻出几年前的Leapmotion感测器,准备用Unity3D做个互动APP,于是连上官网下载SDK.等下载下来一安装调试,瞬间傻眼,居然要求VR设备.我们Lab倒是不缺VR,有几套VIVE ...

  8. 桥接:JS调用安卓方法报错Uncaught Error: Error calling method on NPObject

    说一说自己粗心踩到的一个不算坑的坑: 项目是安卓webview嵌入SPA单页应用页面,涉及到JS调用原生安卓方法,但就是在调用安卓方法时死活一直报错xxx  NPObject一堆错误.写了一个测试页面 ...

  9. rust-vmm 学习

    V0.1.0 feature base knowledge: Architecture of the Kernel-based Virtual Machine (KVM) 用rust-vmm打造未来的 ...

  10. I Count Two Three(打表+排序+二分查找)

    I Count Two Three 二分查找用lower_bound 这道题用cin,cout会超时... AC代码: /* */ # include <iostream> # inclu ...