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].
method 1
思想上類似於快排,找到中位數爲pivot,將所有大於中間元素從前往後放在奇數位上,將所有小於中間元素的從後往前放在偶數位上,這樣就形成錯峯。與快排相比,只是partition函數之後的操作不一樣。
這裏(n|1)是求出不小於n的第一個奇數。
1+2*index的意思是,當爲前半部分的數時,newIndex()函數返回右半部分索引;當爲後半部分的數時,取餘操作會返回前半部分索引。這樣就使得比中位數大的數能夠從前往後填,比中位數小的數從後往前填。
當然有點難理解,但思想理解了,怎麼填就相對靈活許多。
int newIndex(int index, int n) {
return (1 + 2 * index) % (n | 1);
}
void wiggleSort(vector<int>& nums) {
int n = nums.size();
// Step 1: Find the median
vector<int>::iterator nth = next(nums.begin(), n / 2);
nth_element(nums.begin(), nth, nums.end());
int median = *nth;
int left = 0, right = n - 1, i = 0;
while (i <= right){
if (nums[newIndex(i, n)] > median){
swap(nums[newIndex(left, n)], nums[newIndex(i, n)]);
left++;
i++;
}
else if (nums[newIndex(i, n)] < median){
swap(nums[newIndex(right, n)], nums[newIndex(i, n)]);
right--;
}
else i++;
}
}
https://leetcode.com/problems/wiggle-sort-ii/discuss/77681/O(n)-time-O(1)-space-solution-with-detail-explanations
https://leetcode.com/problems/wiggle-sort-ii/discuss/77682/Step-by-step-explanation-of-index-mapping-in-Java
summary
- 快排的變化:可能pivot不同,也可能選出pivot如何移動元素也不同。
- 使用快排pivot思想將集合按大小一分爲二。