-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathk-largest-quickselect.py
47 lines (36 loc) · 997 Bytes
/
k-largest-quickselect.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import random
import unittest
def partition(arr, lo, hi):
pivot = arr[(lo + hi) // 2]
arr[hi], arr[pivot] = arr[pivot], arr[hi]
i = lo
for j in range(lo, hi):
if arr[i] < pivot:
arr[i], arr[j] = arr[j], arr[i]
i += 1
arr[i + 1], arr[hi] = arr[hi], arr[i + 1]
return i + 1
def quickselect(arr, lo, hi, k):
while lo <= hi:
p = partition(arr, lo, hi)
if k == p:
return arr[p]
if k > p:
lo = p + 1
else:
hi = p - 1
return -1
def klargest(arr, k):
n = len(arr) - 1
k = n - k
return quickselect(arr, 0, n, k)
class TestClass(unittest.TestCase):
def test_basic_select(self):
maxlen = 10 * 3
arr = [random.randrange(maxlen)] * maxlen
k = random.randrange(maxlen)
actual = klargest(arr, k)
expected = sorted(arr)[-k]
self.assertEqual(actual, expected)
if __name__ == "__main__":
unittest.main()