题目
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++里面有现成的库函数nth_element())
- 荷兰国旗问题
这里我们着重强调下荷兰国旗问题在本题中的应用。因为奇偶索引的关系,导致数组被分成了三部分,我们维护三个指针:
- 起始指针(奇数位)
- 末尾指针(偶数位)
- 当前指针(扫描指针)
我们利用扫描指针扫描数组,大于中位数的我们将其与奇数位互换,小于中位数的我们将其与偶数位互换,等于中位数的,我们将扫描指针自增1。
class Solution {
public:
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 midvalue = *midptr;
//define
#define A(i) nums[(1+2*i)%(nums.size()|1)]
//DNF
int i=0,j=0,k=n-1;
//i begin,k end,j scan
while(j<=k)
{
if(A(j)>midvalue)
{
swap(A(i++),A(j++));
}
else if(A(j)<midvalue)
{
swap(A(j),A(k--));
}
else
j++;
}
}
};