Skip to content

Commit 4078dd6

Browse files
committed
update 324 Wiggle Sort II
1 parent efd4c88 commit 4078dd6

File tree

5 files changed

+174
-1
lines changed

5 files changed

+174
-1
lines changed

Combination/324_WiggleSortII.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* @Author: [email protected]
3+
* @Last Modified time: 2016-07-29 10:53:41
4+
*/
5+
6+
class Solution {
7+
public:
8+
/*
9+
Sort needed.
10+
Sort the array(small to big), and cut into two parts:
11+
For even size, left half size==right half size,
12+
For odd size, left half size==right half size+1.
13+
(smaller part there may be one more number.)
14+
15+
Then put the smaller half of the numbers on the even indexes,
16+
and the larger half on the odd indexes.
17+
Here iterate from the back of two halves,
18+
so that the duplicates between two parts can be split apart.
19+
20+
Clear solutionm, explanation and proof can be found here:
21+
https://leetcode.com/discuss/76965/3-lines-python-with-explanation-proof
22+
*/
23+
void wiggleSort(vector<int>& nums) {
24+
vector<int> sorted(nums);
25+
sort(sorted.begin(), sorted.end());
26+
int left = (nums.size()+1) / 2, right = nums.size();
27+
for(int i=0; i<nums.size(); i++){
28+
nums[i] = i & 0x1 ? sorted[--right] : sorted[--left];
29+
}
30+
}
31+
};
32+
33+
34+
class Solution_2 {
35+
public:
36+
/*
37+
O(n)-time O(1)-space solution, no sort here.
38+
39+
Find the kth smallest element, where k is the half the size (if size is even)
40+
or half the size+1 (if size is odd).
41+
42+
Then do a three-way-partition, so that they can be split in two parts.
43+
Number in left parts <= those in right parts and the duplicates are around median.
44+
45+
Then put the smaller half of the numbers on the even indexes,
46+
and the larger half on the odd indexes.
47+
Here iterate from the back of two halves,
48+
so that the duplicates between two parts can be split apart.
49+
50+
According to:
51+
https://leetcode.com/discuss/77133/o-n-o-1-after-median-virtual-indexing
52+
https://discuss.leetcode.com/topic/38189/clear-java-o-n-avg-time-o-n-space-solution-using-3-way-partition
53+
*/
54+
void wiggleSort(vector<int>& nums) {
55+
int mid = (nums.size()+1) / 2;
56+
auto midptr = nums.begin() + mid;
57+
nth_element(nums.begin(), midptr, nums.end());
58+
int mid_val = *midptr;
59+
60+
vector<int> nums_p(nums);
61+
three_way_partition(nums_p, mid_val);
62+
int right = nums.size();
63+
for(int i=0; i<nums.size(); i++){
64+
nums[i] = i & 0x1 ? nums_p[--right] : nums_p[--mid];
65+
}
66+
}
67+
68+
void three_way_partition(vector<int> &nums, int mid_val){
69+
int i=0, j=0, n=nums.size()-1;
70+
while(j<=n){
71+
if(nums[j] < mid_val){
72+
swap(nums[i++], nums[j++]);
73+
}
74+
else if(nums[j] > mid_val){
75+
swap(nums[j], nums[n--]);
76+
}
77+
else{
78+
j++;
79+
}
80+
}
81+
}
82+
};
83+
84+
/*
85+
[4, 5, 5, 6]
86+
[1, 5, 1, 1, 6, 4]
87+
[1, 3, 2, 2, 3, 1]
88+
*/

Combination/324_WiggleSortII.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#! /usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
5+
6+
class Solution(object):
7+
def wiggleSort(self, nums):
8+
""" Sort needed.
9+
Sort the array(small to big), and cut into two parts:
10+
For even size, left half size==right half size,
11+
For odd size, left half size==right half size+1.
12+
(smaller part there may be one more number.)
13+
14+
Then put the smaller half of the numbers on the even indexes,
15+
and the larger half on the odd indexes.
16+
Here iterate from the back of two halves,
17+
so that the duplicates between two parts can be split apart.
18+
19+
Clear solutionm, explanation and proof can be found here:
20+
https://leetcode.com/discuss/76965/3-lines-python-with-explanation-proof
21+
"""
22+
nums.sort()
23+
# half = len(nums[::2]) or half = (len(nums) + 1) // 2
24+
# nums[::2], nums[1::2] = nums[:half][::-1], nums[half:][::-1]
25+
half = len(nums[::2]) - 1
26+
nums[::2], nums[1::2] = nums[half::-1], nums[:half:-1]
27+
28+
29+
class Solution_2(object):
30+
def wiggleSort(self, nums):
31+
""" O(n)-time O(1)-space solution, no sort here.
32+
33+
Find the kth smallest element, where k is the half the size (if size is even)
34+
or half the size+1 (if size is odd).
35+
36+
Then do a three-way-partition, so that they can be split in two parts.
37+
Number in left parts <= those in right parts and the duplicates are around median.
38+
39+
Then put the smaller half of the numbers on the even indexes,
40+
and the larger half on the odd indexes.
41+
Here iterate from the back of two halves,
42+
so that the duplicates between two parts can be split apart.
43+
44+
According to:
45+
https://leetcode.com/discuss/77133/o-n-o-1-after-median-virtual-indexing
46+
https://discuss.leetcode.com/topic/38189/clear-java-o-n-avg-time-o-n-space-solution-using-3-way-partition
47+
"""
48+
mid = len(nums[::2])
49+
mid_val = self.findKthLargest(nums, mid)
50+
self.three_way_partition(nums, mid_val)
51+
52+
nums[::2], nums[1::2] = nums[mid - 1::-1], nums[:mid - 1:-1]
53+
54+
def three_way_partition(self, nums, mid_val):
55+
""" Dutch national flag problem.
56+
57+
Refer to:
58+
https://en.wikipedia.org/wiki/Dutch_national_flag_problem
59+
"""
60+
i, j, n = 0, 0, len(nums) - 1
61+
while j <= n:
62+
if nums[j] < mid_val:
63+
nums[i], nums[j] = nums[j], nums[i]
64+
i += 1
65+
j += 1
66+
elif nums[j] > mid_val:
67+
nums[n], nums[j] = nums[j], nums[n]
68+
n -= 1
69+
else:
70+
j += 1
71+
72+
def findKthLargest(self, nums, k):
73+
""" Can be done in O(logn) with partition. Here use built-in heap method.
74+
"""
75+
import heapq
76+
return heapq.nsmallest(k, nums)[-1]
77+
78+
"""
79+
[4, 5, 5, 6]
80+
[1, 5, 1, 1, 6, 4]
81+
[1, 3, 2, 2, 3, 1]
82+
"""

DivideConquer/215_KthLargestElementArray.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ class Solution(object):
88
def findKthLargest(self, nums, k):
99
return sorted(nums)[-k]
1010

11+
12+
class Solution_2(object):
1113
# QuickSelect, according to:
1214
# http://www.cs.yale.edu/homes/aspnes/pinewiki/QuickSelect.html
13-
def findKthLargest_2(self, nums, k):
15+
def findKthLargest(self, nums, k):
1416
pivot = nums[0]
1517
nums1, nums2 = [], []
1618
for num in nums:

More.md renamed to Others/More.md

File renamed without changes.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@
320320
* 140. [Word Break II](Combination/140_WordBreakII.py)
321321
* 146. [LRU Cache](Combination/146_LRUCache.py)
322322
* 300. [Longest Increasing Subsequence](Combination/300_LongestIncreasingSubsequence.py)
323+
* 324. [Wiggle Sort II](Combination/324_WiggleSortII.py)
323324
* 329. [Longest Increasing Path in a Matrix](Combination/329_LongestIncreasingPathInMatrix.py)
324325
* 355. [Design Twitter](Combination/355_DesignTwitter.py)
325326

0 commit comments

Comments
 (0)