[LeetCode] 324. Wiggle Sort II 摆动排序 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?
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的更多相关文章
- LeetCode 280. Wiggle Sort (摆动排序)$
Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...
- 324 Wiggle Sort II 摆动排序 II
给定一个无序的数组nums,将它重新排列成nums[0] < nums[1] > nums[2] < nums[3]...的顺序.例子:(1) 给定nums = [1, 5, 1, ...
- leetcode 324 Wiggle Sort 2
利用中位数的概念,中位数就是将一组数分成2等份(若为奇数,则中位数既不属于左也不属于右,所以是2等份),其一组数中任何一个元素都大于等于另一组数 那么我们是不是只要一左一右配合着插入,就保证了差值+- ...
- [LeetCode] 280. Wiggle Sort 摆动排序
Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...
- leetcode 280.Wiggle Sort 、324. Wiggle Sort II
Wiggle Sort: 注意:解法一是每次i增加2,题目不是保证3个3个的情况,而是整个数组都要满足要求. 解法一错误版本: 如果nums的长度是4,这种情况下nums[i+1]会越界.但是如果你用 ...
- Leetcode 324.摆动排序II
摆动排序II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序. 示例 1: 输入: nums ...
- Java实现 LeetCode 324 摆动排序 II
324. 摆动排序 II 给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]- 的顺序. 示例 1: 输入: n ...
- [LeetCode] Wiggle Sort II 摆动排序
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
- [LeetCode] Wiggle Sort II 摆动排序之二
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]... ...
随机推荐
- Kotlin反射重要组件与流程详解
继续学习Kotlin反射,我们知道对于Java的反射类是Class,而在Kotlin中的反射类是KClass,而在Java当中对于反射中的方法是用Method,而在Kotlin中是用KFunction ...
- winafl 源码分析
前言 winafl 是 afl 在 windows 的移植版, winafl 使用 dynamorio 来统计代码覆盖率,并且使用共享内存的方式让 fuzzer 知道每个测试样本的覆盖率信息.本文主要 ...
- danci3
permit 英 [pə'mɪt] 美 [pɚ'mɪt] vi. 许可:允许 vt. 许可:允许 n. 许可证,执照 encapsulate 英 [ɪn'kæpsjʊleɪt; en-] 美 [ɪn' ...
- Hadoop跨集群迁移数据(整理版)
1. 什么是DistCp DistCp(分布式拷贝)是用于大规模集群内部和集群之间拷贝的工具.它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成.它把文件和目录的列表作为map任务的 ...
- go 学习 (五):包管理
一.设置环境变量 二.启用 go modules 功能 并设置代理 https://goproxy.io/zh/ 补充: GO111MODULE 有三个值:on.off.auto GO111MODU ...
- TED演讲:别不信,你只需20个小时,就能学会任何事情!
https://www.bilibili.com/video/av50668972/?spm_id_from=333.788.videocard.3 two years ago, my life ch ...
- Parametric and Nonparametric Algorithms
即参数化算法和非参数化算法. 参数化机器学习算法 可以大大简化学习过程,也可以限制可以学到的东西,将函数简化为已知形式的算法称为参数化机器学习算法.算法包括两个步骤: 为函数选择一个form. 从训练 ...
- 【loj2568】【APIO2016】【学习笔记 左偏树】烟花表演
题目 一棵树,\(n\)个非叶子节点,编号为\(1-n\),\(m\)个叶子节点,编号为\(n+1-n+m\) 每条边有边权,修改边权的代价为\(|a-b|\) ; 定义一个叶子的距离为到1(根节点) ...
- 这里是DDOSvoid的blog
由于博主已经退役,博客现由 @一扶苏一 代为维护. DDOSvoid 在生前退役前写下了大量的 blog 存在本地,现在由他的弟子 一扶苏一 整理编纂成为题单慢慢上传,是为<论语>< ...
- CORS跨域资源共享总结
1.CORS简述 CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源(协议 + 域名 + 端口)服务 ...