Leetcode 324. Wiggle Sort II

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

  1. 快排的變化:可能pivot不同,也可能選出pivot如何移動元素也不同。
  2. 使用快排pivot思想將集合按大小一分爲二。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章