324. Wiggle Sort II
来源:互联网 发布:网络推广服务商 编辑:程序博客网 时间:2024/05/16 16:17
Given an unsorted array nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example:
(1) Given nums = [1, 5, 1, 1, 6, 4]
, one possible answer is [1, 4, 1, 5, 1, 6]
.
(2) Given nums = [1, 3, 2, 2, 3, 1]
, 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?
Solution:
solve it in O(n) space is easy, we could first find the median of the nums, and partition the array by smaller | median | larger, it takes O(1) time,
we want to put median numbers in the smallest odd positions and largest even positions to separate them as far as possible to avoid nums[i] == nums[i + 1];
for the index
0 1 2 3 4 5 6 they will end to be
1 3 5 0 2 4 6
How to get this? from https://discuss.leetcode.com/topic/41464/step-by-step-explanation-of-index-mapping-in-java/14
This is to explain why mapped index formula is (1 + 2*index) % (n | 1)
Notice that by placing the median in it's place in the array we divided the array in 3 chunks: all numbers less than median are in one side, all numbers larger than median are on the other side, median is in the dead center of the array.
We want to place any a group of numbers (larger than median) in odd slots, and another group of numbers (smaller than median) in even slots. So all numbers on left of the median < n / 2 should be in odd slots, all numbers on right of the median > n / 2 should go into even slots (remember that median is its correct place at n / 2)
PS: I'm ignoring the discussion of odd/even array length for simplicity.
So let's think about the first group in the odd slots, all numbers is the left side of the array should go into these odd slots. What's the formula for it? Naturally it would be:
(1 + 2 x index) % n
All these indexes are less than n / 2 so multiplying by 2 and add 1 (to make them go to odd place) and then mod by n will always guarantee that they are less than n.
Original Index => Mapped Index
0 => (1 + 2 x 0) % 6 = 1 % 6 = 1
1 => (1 + 2 x 1) % 6 = 3 % 6 = 3
2 => (1 + 2 x 2) % 6 = 5 % 6 = 5
These are what's less than median, if we continue this with indexes 3, 4, 5 we will cycle again:
3 => (1 + 2 x 3) % 6 = 7 % 6 = 1
4 => (1 + 2 x 4) % 6 = 9 % 6 = 3
5 => (1 + 2 x 5) % 6 = 11 % 6 = 5
and we don't want that, so for indexes larger than n/2 we want them to be even, (n|1) does that exactly. What n|1 does it that it gets the next odd number to n if it was even
if n = 6 for example 110 | 1 = 111 = 7
if n = 7 for example 111 | 1 = 111 = 7
and this is what we want, instead of cycling the odd numbers again we want them to be even, and odd % odd number is even so updating the formula to :
(1 + 2*index) % (n | 1)
Then we have:
3 => (1 + 2 x 3) % 7 = 7 % 7 = 0
4 => (1 + 2 x 4) % 7 = 9 % 7 = 2
5 => (1 + 2 x 5) % 7 = 11 % 7 = 4
Code:
public class Solution { public void wiggleSort(int[] nums) { int mid = findKth(nums,(nums.length - 1)/ 2,0,nums.length-1); partition(nums,mid); } public int mapIndex(int len, int i){ return (2*i + 1) % (len | 1); } public void partition(int[] nums, int val){ int len = nums.length; int l = 0; int r = nums.length - 1; int i = 0; while(i <= r){ int curIndex = mapIndex(len,i); if(nums[curIndex] > val){ swap(nums,curIndex,mapIndex(len,l)); i++;l++; } else if(nums[curIndex] == val){ i++; } else { swap(nums,curIndex,mapIndex(len,r)); r--; } } } public void swap(int[] nums, int i, int j){ int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } public int findKth(int[] nums, int k, int start, int end){ int index= partition(nums,start,end); if(index == k) return nums[k]; else if(index > k) return findKth(nums,k,start,index - 1); else return findKth(nums,k,index + 1, end); } public int partition(int[] nums, int start, int end){ if(start == end) return start; int p = nums[start]; while(start < end){ while(start < end && nums[end] > p){ end--; } nums[start] = nums[end]; while(start < end && nums[start] <= p){ start++; } nums[end] = nums[start]; } nums[start] = p; return start; }}
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II**
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- 324. Wiggle Sort II
- # 324. Wiggle Sort II
- 324. Wiggle Sort II
- Java HashMap的工作原理
- 单选按钮(RadioBox)的操作
- 卷积和积分运算
- CString string char* char[] 之间的转换
- 欢迎使用CSDN-markdown编辑器
- 324. Wiggle Sort II
- Redis、Memcache和MongoDB的区别
- LeetCode 算法刷题(7)
- Spring Boot安装
- Django-web development configuration part2
- (六)颜色方案
- MySQL mytop 安装与监控
- Linux服务器使用Gitblit搭建Git服务器之使用war包部署在Tomcat下(二)
- 在matlab上实现遗传算法解决TSP旅行者问题