标签(空格分隔): leetcode
1. 原题
Given an unsorted array nums, reorder it such that nums[0] < nums1 > 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?
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
2. 分析:
- 只要输出一种满足以上需求的数组就可以
- 排序之后, 只要按中位数分为2组,比如:[1,2,3,4,5,6,7,8] ==>
[1,2,3,4], [5,6,7,8], 然后按照顺序组合[1, 5], [2, 6], [3, 7], [4, 8]。然后就可以得到满足的数组:[1,5,2,6,3,7,4,8]。当出现奇数长度的数组的时候, 比如原来的数组加上一个5, 那么就可以在最后补上5变成[1,5,2,6,3,7,4,8,5] - 找到中位数的下一位: A[(len - 1)/2 + 1]
这一位到数组结尾都大于对称位的数
3. 需要注意的一些细节
在第二点的分析中有一点错误, 就是需要从后往前填数,不能从前往后
比如: [4,5,5,6]正确输出应该是[5,6,5,4]
按照分析中的算法, 结果应该是[4,5] + [5,6] ==> [4,5,5,6]
假设我们根据 len的奇偶和下标 i 的奇偶来判断,当 len 为偶数的时候, 先填大的部分,再填小的部分 [5, 6] + [4, 5] ==> [5, 4, 6, 5], 那么就不符合要求了。从后往前填, 在开始的时候,如果len是一个奇数, 需要先在后面填小的,这样中位数就会填在第一位, 中位数的下一位是大于他的数
4. 代码
void wiggleSort(vector<int>& nums) {
vector<int> sorted(nums);
sort(sorted.begin(), sorted.end());
for (int i=nums.size()-1, j=0, k=i/2+1; i>=0; i--)
nums[i] = sorted[i&1 ? k++ : j++];
}