-
Notifications
You must be signed in to change notification settings - Fork 0
/
SortAnArray2.py
116 lines (90 loc) · 3.37 KB
/
SortAnArray2.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
class Solution:
def sortArray(self, nums: List[int]) -> List[int]:
# Min Heap solution:
min_heap = MinHeap(nums)
return [min_heap.pop() for _ in range(len(nums))]
# Max Heap solution:
# negatives = [-num for num in nums]
# max_heap = MaxHeap(negatives)
# return [-max_heap.pop() for _ in range(len(negatives))]
class MinHeap:
def __init__(self, arr: List = None):
if arr is None:
self.heap = []
else:
self.heap = arr
self.build_min_heap(arr)
def push(self, val: int):
self.heap.append(val)
self.bubble_up(len(self.heap) - 1)
def pop(self) -> int:
if not self.heap:
raise IndexError("pop from empty heap")
self.heap[0], self.heap[-1] = self.heap[-1], self.heap[0]
res = self.heap.pop()
if self.heap:
self.min_heapify(0, len(self.heap))
return res
def build_min_heap(self, arr: List):
# assuming `arr` is a list representation of an almost complete binary tree
self.heap = arr
n = len(arr)
for i in range(n // 2, -1, -1):
self.min_heapify(i, n)
def min_heapify(self, idx: int, heap_size: int):
left = 2 * idx + 1
right = left + 1
smallest = idx
if left < heap_size and self.heap[left] < self.heap[idx]:
smallest = left
if right < heap_size and self.heap[right] < self.heap[smallest]:
smallest = right
if smallest != idx:
self.heap[idx], self.heap[smallest] = self.heap[smallest], self.heap[idx]
self.min_heapify(smallest, heap_size)
def bubble_up(self, idx: int):
parent = (idx - 1) // 2
while idx > 0 and self.heap[parent] > self.heap[idx]:
self.heap[idx], self.heap[parent] = self.heap[parent], self.heap[idx]
idx = parent
parent = (idx - 1) // 2
class MaxHeap:
def __init__(self, arr: List = None):
if arr is None:
self.heap = []
else:
self.heap = arr
self.build_max_heap(arr)
def push(self, val: int):
self.heap.append(val)
self.bubble_up(len(self.heap) - 1)
def pop(self) -> int:
if not self.heap:
raise IndexError("pop from empty heap")
self.heap[0], self.heap[-1] = self.heap[-1], self.heap[0]
res = self.heap.pop()
if self.heap:
self.max_heapify(0)
return res
def build_max_heap(self, arr: List):
n = len(arr)
for i in range(n // 2, -1, -1):
self.max_heapify(i)
def max_heapify(self, idx: int):
heap_size = len(self.heap)
left = 2 * idx + 1
right = left + 1
largest = idx
if left < heap_size and self.heap[left] > self.heap[largest]:
largest = left
if right < heap_size and self.heap[right] > self.heap[largest]:
largest = right
if largest != idx:
self.heap[largest], self.heap[idx] = self.heap[idx], self.heap[largest]
self.max_heapify(largest)
def bubble_up(self, idx: int):
parent = (idx - 1) // 2
while idx > 0 and self.heap[idx] > self.heap[parent]:
self.heap[idx], self.heap[parent] = self.heap[parent], self.heap[idx]
idx = parent
parent = (idx - 1) // 2