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?
基本思路是找到中间的那个数,人后把原数列分成两组,一组小于等于中间数,另外一组大于中间数,然后把这两数组排序,为皮面重复的数字
交错在一起,从尾部开始交替插入数字。
c++实现:
class Solution {
public:
void wiggleSort(vector<int>& nums) {
// Write your code
// Find a median.
sort(nums.begin(),nums.end());
int mid=(nums.size()-1)/2;
vector<int> small;
vector<int> big;
for (int i=0;i<nums.size();i++)
if (i<=mid)
small.push_back(nums[i]);
else
big.push_back(nums[i]);
for (int i=0;i<nums.size();i++){
if (i%2==0)
nums[i]=small[small.size()-1-i/2];
else
nums[i]=big[big.size()-1-i/2];
}
}
};
class Solution {
public:
void wiggleSort(vector<int>& nums) {
// Write your code
// Find a median.
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;
while (j <= k) {
if (A(j) > mid)
swap(A(i++), A(j++));
else if (A(j) < mid)
swap(A(j), A(k--));
else
j++;
}
}
};