Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f73e7a0

Browse files
committed
Add C++ solutions for Chapter 8 (Heaps)
1 parent 502f5bd commit f73e7a0

5 files changed

+200
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <vector>
2+
#include <queue>
3+
#include "ds/ListNode.h"
4+
using ds::ListNode;
5+
6+
/**
7+
* Definition of ListNode:
8+
* struct ListNode {
9+
* int val;
10+
* ListNode* next;
11+
* ListNode(int val = 0, ListNode* next = nullptr) : val(val), next(next) {}
12+
* };
13+
*/
14+
15+
ListNode* combineSortedLinkedLists(std::vector<ListNode*>& lists) {
16+
// Min-heap (priority queue) storing (node value, node pointer) pairs.
17+
// std::pair's built-in comparison ensures the heap is ordered by value.
18+
typedef std::pair<int, ListNode*> NodePair;
19+
std::priority_queue<NodePair, std::vector<NodePair>, std::greater<NodePair>> heap;
20+
// Push the head of each linked list into the heap.
21+
for (ListNode* head : lists) {
22+
if (head) {
23+
heap.push(std::make_pair(head->val, head));
24+
}
25+
}
26+
// Set a dummy node to point to the head of the output linked list.
27+
ListNode dummy(-1);
28+
// Create a pointer to iterate through the combined linked list as
29+
// we add nodes to it.
30+
ListNode* curr = &dummy;
31+
while (!heap.empty()) {
32+
// Pop the node with the smallest value from the heap and add it
33+
// to the output linked list.
34+
NodePair smallestNodePair = heap.top();
35+
heap.pop();
36+
ListNode* smallestNode = smallestNodePair.second;
37+
curr->next = smallestNode;
38+
curr = curr->next;
39+
// Push the popped node's subsequent node to the heap.
40+
if (smallestNode->next) {
41+
heap.push(std::make_pair(smallestNode->next->val, smallestNode->next));
42+
}
43+
}
44+
return dummy.next;
45+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <vector>
2+
#include <string>
3+
#include <unordered_map>
4+
#include <queue>
5+
6+
std::vector<std::string> kMostFrequentStringsMaxHeap(std::vector<std::string>& strs, int k) {
7+
// Create a hash map that counts the frequency of each string.
8+
std::unordered_map<std::string, int> freqs;
9+
for (auto& str : strs) {
10+
freqs[str]++;
11+
}
12+
// Define a custom comparator for the priority queue.
13+
auto cmp = [](std::pair<int, std::string>& a, std::pair<int, std::string>& b) {
14+
// Prioritize lexicographical order for strings with equal
15+
// frequencies.
16+
if (a.first == b.first) {
17+
return a.second > b.second;
18+
}
19+
// Otherwise, prioritize strings with higher frequencies.
20+
return a.first < b.first;
21+
};
22+
// Create the max heap using the comparator and push all
23+
// frequency-string pairs into the heap. Take note that
24+
// std::priority_queue is inherently a max-heap.
25+
std::priority_queue<std::pair<int, std::string>,
26+
std::vector<std::pair<int, std::string>>,
27+
decltype(cmp)> maxHeap(cmp);
28+
for (auto& entry : freqs) {
29+
maxHeap.push(std::make_pair(entry.second, entry.first));
30+
}
31+
// Pop the most frequent string off the heap 'k' times and return
32+
// these 'k' most frequent strings.
33+
std::vector<std::string> res;
34+
for (int i = 0; i < k && !maxHeap.empty(); i++) {
35+
res.push_back(maxHeap.top().second);
36+
maxHeap.pop();
37+
}
38+
return res;
39+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <vector>
2+
#include <string>
3+
#include <unordered_map>
4+
#include <queue>
5+
#include <algorithm>
6+
7+
std::vector<std::string> kMostFrequentStringsMinHeap(std::vector<std::string>& strs, int k) {
8+
std::unordered_map<std::string, int> freqs;
9+
for (auto& str : strs) {
10+
freqs[str]++;
11+
}
12+
// Since this is a min-heap comparator, we can use the same
13+
// comparator as the one used in the max-heap, but reversing the
14+
// inequality signs to invert the priority.
15+
auto cmp = [](std::pair<int, std::string>& a, std::pair<int, std::string>& b) {
16+
if (a.first == b.first) {
17+
return a.second < b.second;
18+
}
19+
return a.first > b.first;
20+
};
21+
std::priority_queue<
22+
std::pair<int, std::string>,
23+
std::vector<std::pair<int, std::string>>,
24+
decltype(cmp)
25+
> minHeap(cmp);
26+
for (auto& entry : freqs) {
27+
minHeap.push(std::make_pair(entry.second, entry.first));
28+
// If heap size exceeds 'k', pop the lowest frequency string to
29+
// ensure the heap only contains the 'k' most frequent words so
30+
// far.
31+
if (minHeap.size() > k) {
32+
minHeap.pop();
33+
}
34+
}
35+
// Return the 'k' most frequent strings by popping the remaining 'k'
36+
// strings from the heap. Since we're using a min-heap, we need to
37+
// reverse the result after popping the elements to ensure the most
38+
// frequent strings are listed first.
39+
std::vector<std::string> res;
40+
for (int i = 0; i < k && !minHeap.empty(); i++) {
41+
res.push_back(minHeap.top().second);
42+
minHeap.pop();
43+
}
44+
std::reverse(res.begin(), res.end());
45+
return res;
46+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <queue>
2+
#include <vector>
3+
4+
class MedianOfAnIntegerStream {
5+
public:
6+
MedianOfAnIntegerStream() {}
7+
8+
void add(int num) {
9+
// If 'num' is less than or equal to the max of 'leftHalf', it
10+
// belongs to the left half.
11+
if (leftHalf.empty() || num <= leftHalf.top()) {
12+
leftHalf.push(num);
13+
// Rebalance the heaps if the size of 'leftHalf'
14+
// exceeds the size of 'rightHalf' by more than one.
15+
if (leftHalf.size() > rightHalf.size() + 1) {
16+
rightHalf.push(leftHalf.top());
17+
leftHalf.pop();
18+
}
19+
} else {
20+
// Otherwise, it belongs to the right half.
21+
rightHalf.push(num);
22+
// Rebalance the heaps if 'rightHalf' is larger than
23+
// 'leftHalf'.
24+
if (leftHalf.size() < rightHalf.size()) {
25+
leftHalf.push(rightHalf.top());
26+
rightHalf.pop();
27+
}
28+
}
29+
}
30+
31+
double getMedian() {
32+
if (leftHalf.size() == rightHalf.size()) {
33+
return (leftHalf.top() + rightHalf.top()) / 2.0;
34+
}
35+
return leftHalf.top();
36+
}
37+
38+
private:
39+
// Max-heap for the left half.
40+
std::priority_queue<int> leftHalf;
41+
// Min-heap for the right half.
42+
std::priority_queue<int, std::vector<int>, std::greater<int>> rightHalf;
43+
};

cpp/Heaps/sort_a_k_sorted_array.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <vector>
2+
#include <queue>
3+
4+
std::vector<int> sortAKSortedArray(std::vector<int>& nums, int k) {
5+
// Populate a min-heap with the first k + 1 values in 'nums'.
6+
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
7+
int n = nums.size();
8+
for (int i = 0; i <= k && i < n; i++) {
9+
minHeap.push(nums[i]);
10+
}
11+
// Replace elements in the array with the minimum from the heap at each
12+
// iteration.
13+
int insertIndex = 0;
14+
for (int i = k + 1; i < n; i++) {
15+
nums[insertIndex] = minHeap.top();
16+
minHeap.pop();
17+
insertIndex++;
18+
minHeap.push(nums[i]);
19+
}
20+
// Pop the remaining elements from the heap to finish sorting the array.
21+
while (!minHeap.empty()) {
22+
nums[insertIndex] = minHeap.top();
23+
minHeap.pop();
24+
insertIndex++;
25+
}
26+
return nums;
27+
}

0 commit comments

Comments
 (0)