-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
count-nodes-that-are-great-enough.cpp
46 lines (43 loc) · 1.48 KB
/
count-nodes-that-are-great-enough.cpp
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
// Time: O(k * h)
// Space: O(k + h)
// merge sort
class Solution {
public:
int countGreatEnoughNodes(TreeNode* root, int k) {
const auto& merge_at_most_k = [&](const auto& a, const auto& b) {
vector<int> result;
result.reserve(k);
for (int i = 0, j = 0; i < size(a) || j < size(b);) {
if (j == size(b) || (i < size(a) && a[i] < b[j])) {
result.emplace_back(a[i++]);
} else {
result.emplace_back(b[j++]);
}
if (size(result) == k) {
break;
}
}
return result;
};
int result = 0;
const function<vector<int> (TreeNode *node)> merge_sort = [&](TreeNode *node) {
if (!node) {
return vector<int>{};
}
const auto& left = merge_sort(node->left), &right = merge_sort(node->right);
auto smallest_k = merge_at_most_k(left, right);
const auto& i = distance(cbegin(smallest_k), lower_bound(cbegin(smallest_k), cend(smallest_k), node->val));
if (i == k) {
++result;
} else {
smallest_k.insert(begin(smallest_k) + i, node->val);
if (size(smallest_k) == k + 1) {
smallest_k.pop_back();
}
}
return smallest_k;
};
merge_sort(root);
return result;
}
};