How to manage the processes running in the operating system.
listen music, download files and write essay
Have to sort every time a new task arrives?
Insert to maintain order every time?
Very fast for getting the lowest/highest priority element.
100
/ \
19 36
/ \ / \
17 3 25 1
2
/ \
19 3
/ \ / \
20 31 5 8
max-heap
min-heap
90
/ \
70 50
/ \ / \
65 44 30 20
/ \ /
35 21 8
80
90
/ \
70 50
/ \ / \
65 44 30 20
/ \ / \
35 21 8 80
90
/ \
80 50
/ \ / \
65 70 30 20
/ \ / \
35 21 8 44
90
/ \
70 50
/ \ / \
65 44 30 20
/ \ /
35 21 8
90
/ \
8 50
/ \ / \
65 44 30 20
/ \
35 21
90
/ \
65 50
/ \ / \
35 44 30 20
/ \
8 21
26
26
/
45
45
/
26
45
/ \
26 21
45
/ \
26 21
/
37
45
/ \
37 21
/
26
45
/ \
37 21
/ \
26 89
45
/ \
89 21
/ \
26 37
89
/ \
45 21
/ \
26 37
89
/ \
45 21
/ \ /
26 37 12
89
/ \
45 21
/ \ / \
26 37 12 9
45
/ \
36 18
/ \ / \
53 72 30 48
/ \ /
93 15 35
45
/ \
36 18
/ \ / \
53 72 30 48
/ \ /
93 15 35
45
/ \
36 18
/ \ / \
53 72 30 48
/ \ /
93 15 35
45
/ \
36 18
/ \ / \
93 72 30 48
/ \ /
53 15 35
45
/ \
36 18
/ \ / \
93 72 30 48
/ \ /
53 15 35
45
/ \
36 48
/ \ / \
93 72 30 18
/ \ /
53 15 35
45
/ \
36 48
/ \ / \
93 72 30 18
/ \ /
53 15 35
45
/ \
93 48
/ \ / \
36 72 30 18
/ \ /
53 15 35
45
/ \
93 48
/ \ / \
53 72 30 18
/ \ /
36 15 35
45
/ \
93 48
/ \ / \
53 72 30 18
/ \ /
36 15 35
93
/ \
45 48
/ \ / \
53 72 30 18
/ \ /
36 15 35
93
/ \
72 48
/ \ / \
53 45 30 18
/ \ /
36 15 35
class MyClass implements Comparable<MyClass> {
@override
public int compareTo(final MyClass o) {
return this.val - o.val; // increasing (minHeap)
}
}
PriorityQueue<> heap = new PriorityQueue<>(capacity);
class MyComparator implements Comparator<MyClass> {
public int compare(MyClass a, MyClass b) {
return a.val - b.val; // increasing (minHeap)
}
}
MyComparator myComparator = new MyComparator();
PriorityQueue<MyClass> heap = new PriorityQueue<MyClass>(capacity, myComparator);
PriorityQueue<MyClass> heap = new PriorityQueue<MyClass>(cap, new Comparator<MyClass>() {
public int compare(MyClass a, MyClass b) {
return a.val - b.val; // increasing (minHeap)
}
});
If you can only remember one
always use Comparator
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
public ListNode merge(ListNode[] lists);
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Insert all head nodes into minHeap.
while (minHeap is not empty)
root = minHeap.pop();
Add root into result
Insert root.next into minHeap.
return result
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0)
return null;
Comparator<ListNode> comparator = new Comparator<ListNode> () {
public int compare(ListNode node1, ListNode node2) {
return node1.val - node2.val;
}
};
PriorityQueue<ListNode> minHeap =
new PriorityQueue<ListNode>(lists.length, comparator);
for (int i = 0; i < lists.length; i++) {
if (lists[i] != null) {
minHeap.add(lists[i]);
}
}
ListNode dummy = new ListNode(-1);
ListNode cur = dummy;
while (!minHeap.isEmpty()) {
cur.next = minHeap.poll();
cur = cur.next;
if (cur.next != null)
minHeap.add(cur.next);
}
return dummy.next;
}
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
q = []
for index, each_list in enumerate(lists):
if each_list:
heapq.heappush(q, [each_list.val, index, each_list])
ans = []
dummy = ListNode(-1)
cur = dummy
while q:
v, i, node = heapq.heappop(q)
cur.next = node
cur = cur.next
if node.next:
heapq.heappush(q, [node.next.val, i, node.next])
return dummy.next
This can be used in external merge sort
But usually people will use tournament tree instead of a heap to do the external merge sort
10,2,8,5,20,30
7,9,0,-2,35,21
1,90,80,15,-1,6
2,5,8,10,20,30
-2,0,7,9,21,35
-1,1,6,15,80,90
-2,-1,0,1,2,5
6,7,8,9,10,15
20,21,30,35,80,90
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.
Return [3,3,5,5,6,7].
Note:
You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] ans = new int[n - k + 1];
// PriorityQueue is a min-heap by default, so we reverse with a comparator
PriorityQueue<int[]> maxHeap = new PriorityQueue<>(
(a, b) -> b[0] != a[0] ? Integer.compare(b[0], a[0]) : Integer.compare(b[1], a[1])
);
for (int i = 0; i < k; i++) {
maxHeap.offer(new int[]{nums[i], i});
}
ans[0] = maxHeap.peek()[0];
for (int i = k; i < n; i++) {
maxHeap.offer(new int[]{nums[i], i});
// Remove elements outside the window
while (maxHeap.peek()[1] <= i - k) {
maxHeap.poll();
}
ans[i - k + 1] = maxHeap.peek()[0];
}
return ans;
}
}
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
# 注意 Python 默认的优先队列是小根堆
q = [(-nums[i], i) for i in range(k)]
heapq.heapify(q)
ans = [-q[0][0]]
for i in range(k, n):
heapq.heappush(q, (-nums[i], i))
while q[0][1] <= i - k:
heapq.heappop(q)
ans.append(-q[0][0])
return ans
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return nums;
}
int[] result = new int[nums.length - k + 1];
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
for (int i = 0; i < nums.length; i++) {
if (i >= k) {
minHeap.remove(-nums[i-k]);
}
minHeap.offer(-nums[i]);
if (i >= k - 1) {
result[i - k + 1] = -minHeap.peek();
}
}
return result;
}
What is the time complexity?
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) {
return nums;
}
Deque<Integer> deque = new LinkedList<>();
int[] result = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
if (!deque.isEmpty() && deque.peekFirst() == i - k) {
deque.poll();
}
while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
deque.pollLast();
}
deque.offer(i);
if (i >= k - 1) {
result[i - k + 1] = nums[deque.peekFirst()];
}
}
return result;
}
A better way: Use deque to get O(n) time complexity
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
if not nums or len(nums) == 0:
return nums
queue = deque()
result = [0] * (len(nums) - k + 1)
for i in range(len(nums)):
if queue and queue[0] == i - k:
queue.popleft()
while queue and nums[queue[-1]] < nums[i]:
queue.pop()
queue.append(i)
if i >= k - 1:
result[i - k + 1] = nums[queue[0]]
return result
A better way: Use deque to get O(n) time complexity
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4] and k = 2, return 5.
Note:
You may assume k is always valid, 1 ≤ k ≤ array's length.
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
public int findKthLargest(int[] nums, int k) {
Comparator<Integer> comparator = new Comparator<Integer>() {
public int compare(Integer a, Integer b) {
return a - b;
}
};
PriorityQueue<Integer> minHeap = new PriorityQueue(k, comparator);
for (int i = 0; i < k; i++) {
minHeap.add(nums[i]);
}
for (int i = k; i < nums.length; i++) {
if (nums[i] > minHeap.peek()) {
minHeap.poll();
minHeap.add(nums[i]);
}
}
return minHeap.poll();
}
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
def findKthLargest(self, nums: List[int], k: int) -> int:
minHeap = []
for i in range(k):
heapq.heappush(minHeap, nums[i])
for i in range(k, len(nums)):
if nums[i] > minHeap[0]:
heapq.heappop(minHeap)
heapq.heappush(minHeap, nums[i])
return heapq.heappop(minHeap)
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Examples:
[2,3,4] , the median is 3
[2,3], the median is (2 + 3) / 2 = 2.5
Design a data structure that supports the following two operations:
- void addNum(int num) - Add a integer number from the data stream to the data structure.
- double findMedian() - Return the median of all elements so far.
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
class MedianFinder {
public void addNum(int num);
public double findMedian();
}
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
minHeap
(big nums)
maxHeap
(small nums)
Median
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
minHeap
(big nums)
maxHeap
(small nums)
Median
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
minHeap
(big nums)
maxHeap
(small nums)
Median
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Median
4
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
4
2
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Median
4
2
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Median
4
3
2
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
4
3
2
1
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Median
4
3
2
1
Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
Median
4
3
2
1
5
class MedianFinder {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
// Adds a number into the data structure.
public void addNum(int num) {
if (!minHeap.isEmpty() && num > minHeap.peek()) {
minHeap.offer(num);
} else {
maxHeap.offer(-num);
}
if (minHeap.size() - maxHeap.size() == 2) {
maxHeap.offer(-minHeap.poll());
} else if (maxHeap.size() - minHeap.size() == 2) {
minHeap.offer(-maxHeap.poll());
}
}
// Returns the median of current data stream
public double findMedian() {
if (minHeap.size() > maxHeap.size()) {
return minHeap.peek();
}
if (minHeap.size() < maxHeap.size()) {
return -maxHeap.peek();
}
return (double)(minHeap.peek() - maxHeap.peek()) / 2.0;
}
};
class MedianFinder:
def __init__(self):
self.minHeap = []
self.maxHeap = []
def addNum(self, num: int) -> None:
if len(self.minHeap) > 0 and num > self.minHeap[0]:
heapq.heappush(self.minHeap, num)
else:
heapq.heappush(self.maxHeap, -num)
if len(self.minHeap) - len(self.maxHeap) == 2:
heapq.heappush(self.maxHeap, -heapq.heappop(self.minHeap))
elif len(self.maxHeap) - len(self.minHeap) == 2:
heapq.heappush(self.minHeap, -heapq.heappop(self.maxHeap))
def findMedian(self) -> float:
if len(self.minHeap) > len(self.maxHeap):
return self.minHeap[0]
if len(self.minHeap) < len(self.maxHeap):
return -self.maxHeap[0]
return (self.minHeap[0] - self.maxHeap[0]) / 2.0
class MedianFinder {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>();
// Adds a number into the data structure.
public void addNum(int num) {
minHeap.offer(num);
maxHeap.offer(-minHeap.poll());
if (maxHeap.size() - minHeap.size() > 1) {
minHeap.offer(-maxHeap.poll());
}
}
// Returns the median of current data stream
public double findMedian() {
if (minHeap.size() == maxHeap.size()) {
return (double)(minHeap.peek() - maxHeap.peek()) / 2.0;
}
return -maxHeap.peek();
}
};
class MedianFinder:
def __init__(self):
self.minHeap = []
self.maxHeap = []
def addNum(self, num: int) -> None:
heapq.heappush(self.minHeap, num)
heapq.heappush(self.maxHeap, -heapq.heappop(self.minHeap))
if len(self.maxHeap) - len(self.minHeap) > 1:
heapq.heappush(self.minHeap, -heapq.heappop(self.maxHeap))
def findMedian(self) -> float:
if len(self.minHeap) == len(self.maxHeap):
return (self.minHeap[0] - self.maxHeap[0]) / 2.0
return -self.maxHeap[0]