Given an unsorted array
nums
, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]...
.
Example:
(1) Given
(2) Given
(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.
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?
Can you do it in O(n) time and/or in-place with O(1) extra space?
Solution:
Please refer to this post
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
void wiggleSort(vector<int>& nums) { | |
int n = nums.size(); | |
int mid = n/2; | |
nth_element(nums.begin(), nums.begin() + mid, nums.end()); | |
threeWayPartition(nums, nums[mid]); | |
vector<int> res(n); | |
int largeStart = n-1; | |
int smallStart = (n%2) ? mid : (mid-1); | |
for (int i = 0; i < n; i+=2) | |
res[i] = nums[smallStart--]; | |
for (int i = 1; i < n; i+=2) | |
res[i] = nums[largeStart--]; | |
nums = res; | |
} | |
// this ensures all values equal to the median is in the middle | |
void threeWayPartition(vector<int> &nums, int val) { | |
int i = 0, j = 0; | |
int n = nums.size()-1; | |
while (j <= n){ | |
if (nums[j] < val) | |
swap(nums[i++], nums[j++]); | |
else if (nums[j] > val) | |
swap(nums[j], nums[n--]); | |
else | |
j++; | |
} | |
} | |
}; |
常数空间的解法:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void wiggleSort(vector<int>& nums) { | |
if (nums.empty()) { | |
return; | |
} | |
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; | |
// Step 2: Tri-partie partition within O(n)-time & O(1)-space. | |
auto m = [n](int idx) { return (2 * idx + 1) % (n | 1); }; | |
int first = 0, mid = 0, last = n - 1; | |
while (mid <= last) { | |
//可以把Tri-partie好的数组想象成一个隐形的数组, | |
//在Tri-partie好数组之后,就可以利用(2 * idx + 1) % (n | 1)来填数字了 | |
if (nums[m(mid)] > median) { | |
swap(nums[m(first)], nums[m(mid)]); | |
++first; | |
++mid; | |
} | |
else if (nums[m(mid)] < median) { | |
swap(nums[m(mid)], nums[m(last)]); | |
--last; | |
} | |
else { | |
++mid; | |
} | |
} | |
} |
No comments:
Post a Comment