Skip to content

Commit d59fbab

Browse files
authored
feat: add solutions to lc problem: No.2792 (doocs#1307)
No.2792.Count Nodes That Are Great Enough
1 parent 4a28611 commit d59fbab

File tree

13 files changed

+700
-0
lines changed

13 files changed

+700
-0
lines changed
Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
# [2792. Count Nodes That Are Great Enough](https://leetcode.cn/problems/count-nodes-that-are-great-enough)
2+
3+
[English Version](/solution/2700-2799/2792.Count%20Nodes%20That%20Are%20Great%20Enough/README_EN.md)
4+
5+
## 题目描述
6+
7+
<!-- 这里写题目描述 -->
8+
9+
<p>You are given a <code>root</code> to a binary tree and an integer <code>k</code>. A node of this tree is called <strong>great enough</strong> if the followings hold:</p>
10+
11+
<ul>
12+
<li>Its subtree has <strong>at least</strong> <code>k</code> nodes.</li>
13+
<li>Its value is <b>greater</b> than the value of <strong>at least</strong> <code>k</code> nodes in its subtree.</li>
14+
</ul>
15+
16+
<p>Return<em> the number of nodes in this tree that are great enough.</em></p>
17+
18+
<p>The node <code>u</code> is in the <strong>subtree</strong> of the node&nbsp;<code>v</code>, if <code><font face="monospace">u == v</font></code>&nbsp;or&nbsp;<code>v</code>&nbsp;is an&nbsp;ancestor of <code>u</code>.</p>
19+
20+
<p>&nbsp;</p>
21+
<p><strong class="example">Example 1:</strong></p>
22+
23+
<pre>
24+
<strong>Input:</strong> root = [7,6,5,4,3,2,1], k = 2
25+
<strong>Output:</strong> 3
26+
<strong>Explanation:</strong> Number the nodes from 1 to 7.
27+
The values in the subtree of node 1: {1,2,3,4,5,6,7}. Since node.val == 7, there are 6 nodes having a smaller value than its value. So it&#39;s great enough.
28+
The values in the subtree of node 2: {3,4,6}. Since node.val == 6, there are 2 nodes having a smaller value than its value. So it&#39;s great enough.
29+
The values in the subtree of node 3: {1,2,5}. Since node.val == 5, there are 2 nodes having a smaller value than its value. So it&#39;s great enough.
30+
It can be shown that other nodes are not great enough.
31+
See the picture below for a better understanding.</pre>
32+
33+
<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2700-2799/2792.Count%20Nodes%20That%20Are%20Great%20Enough/images/1.png" style="padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem; width: 300px; height: 167px;" /></p>
34+
35+
<p><strong class="example">Example 2:</strong></p>
36+
37+
<pre>
38+
<strong>Input:</strong> root = [1,2,3], k = 1
39+
<strong>Output:</strong> 0
40+
<strong>Explanation: </strong>Number the nodes from 1 to 3.
41+
The values in the subtree of node 1: {1,2,3}. Since node.val == 1, there are no nodes having a smaller value than its value. So it&#39;s not great enough.
42+
The values in the subtree of node 2: {2}. Since node.val == 2, there are no nodes having a smaller value than its value. So it&#39;s not great enough.
43+
The values in the subtree of node 3: {3}. Since node.val == 3, there are no nodes having a smaller value than its value. So it&#39;s not great enough.
44+
See the picture below for a better understanding.</pre>
45+
46+
<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2700-2799/2792.Count%20Nodes%20That%20Are%20Great%20Enough/images/2.png" style="padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem; width: 123px; height: 101px;" /></p>
47+
48+
<p><strong class="example">Example 3:</strong></p>
49+
50+
<pre>
51+
<strong>Input:</strong> root = [3,2,2], k = 2
52+
<strong>Output:</strong> 1
53+
<strong>Explanation: </strong>Number the nodes from 1 to 3.
54+
The values in the subtree of node 1: {2,2,3}. Since node.val == 3, there are 2 nodes having a smaller value than its value. So it&#39;s great enough.
55+
The values in the subtree of node 2: {2}. Since node.val == 2, there are no nodes having a smaller value than its value. So it&#39;s not great enough.
56+
The values in the subtree of node 3: {2}. Since node.val == 2, there are no nodes having a smaller value than its value. So it&#39;s not great enough.
57+
See the picture below for a better understanding.</pre>
58+
59+
<p><img alt="" src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/2700-2799/2792.Count%20Nodes%20That%20Are%20Great%20Enough/images/3.png" style="padding: 10px; background: rgb(255, 255, 255); border-radius: 0.5rem; width: 123px; height: 101px;" /></p>
60+
61+
<p>&nbsp;</p>
62+
<p><strong>Constraints:</strong></p>
63+
64+
<ul>
65+
<li>The number of nodes in the tree is in the range&nbsp;<code>[1, 10<sup>4</sup>]</code>.<span style="display: none;">&nbsp;</span></li>
66+
<li><code>1 &lt;= Node.val &lt;= 10<sup>4</sup></code></li>
67+
<li><code>1 &lt;= k &lt;= 10</code></li>
68+
</ul>
69+
70+
## 解法
71+
72+
<!-- 这里可写通用的实现逻辑 -->
73+
74+
**方法一:DFS + 大根堆**
75+
76+
我们可以使用 DFS 后序遍历整棵树,对于每个节点,我们维护一个大根堆,堆中存储该节点的所有子树中最小的 k 个节点的值,如果当前节点的值大于堆顶元素,那么该节点就是一个「足够大」的节点,我们将答案加一。
77+
78+
时间复杂度 $O(n \times k \times \log k)$,空间复杂度 $(n \times k)$。其中 $n$ 是树中节点的个数。
79+
80+
<!-- tabs:start -->
81+
82+
### **Python3**
83+
84+
<!-- 这里可写当前语言的特殊实现逻辑 -->
85+
86+
```python
87+
# Definition for a binary tree node.
88+
# class TreeNode:
89+
# def __init__(self, val=0, left=None, right=None):
90+
# self.val = val
91+
# self.left = left
92+
# self.right = right
93+
class Solution:
94+
def countGreatEnoughNodes(self, root: Optional[TreeNode], k: int) -> int:
95+
def push(pq, x):
96+
heappush(pq, x)
97+
if len(pq) > k:
98+
heappop(pq)
99+
100+
def dfs(root):
101+
if root is None:
102+
return []
103+
l, r = dfs(root.left), dfs(root.right)
104+
for x in r:
105+
push(l, x)
106+
if len(l) == k and -l[0] < root.val:
107+
nonlocal ans
108+
ans += 1
109+
push(l, -root.val)
110+
return l
111+
112+
ans = 0
113+
dfs(root)
114+
return ans
115+
```
116+
117+
### **Java**
118+
119+
<!-- 这里可写当前语言的特殊实现逻辑 -->
120+
121+
```java
122+
/**
123+
* Definition for a binary tree node.
124+
* public class TreeNode {
125+
* int val;
126+
* TreeNode left;
127+
* TreeNode right;
128+
* TreeNode() {}
129+
* TreeNode(int val) { this.val = val; }
130+
* TreeNode(int val, TreeNode left, TreeNode right) {
131+
* this.val = val;
132+
* this.left = left;
133+
* this.right = right;
134+
* }
135+
* }
136+
*/
137+
class Solution {
138+
private int ans;
139+
private int k;
140+
141+
public int countGreatEnoughNodes(TreeNode root, int k) {
142+
this.k = k;
143+
dfs(root);
144+
return ans;
145+
}
146+
147+
private PriorityQueue<Integer> dfs(TreeNode root) {
148+
if (root == null) {
149+
return new PriorityQueue<>(Comparator.reverseOrder());
150+
}
151+
var l = dfs(root.left);
152+
var r = dfs(root.right);
153+
for (int x : r) {
154+
l.offer(x);
155+
if (l.size() > k) {
156+
l.poll();
157+
}
158+
}
159+
if (l.size() == k && l.peek() < root.val) {
160+
++ans;
161+
}
162+
l.offer(root.val);
163+
if (l.size() > k) {
164+
l.poll();
165+
}
166+
return l;
167+
}
168+
}
169+
```
170+
171+
### **C++**
172+
173+
```cpp
174+
/**
175+
* Definition for a binary tree node.
176+
* struct TreeNode {
177+
* int val;
178+
* TreeNode *left;
179+
* TreeNode *right;
180+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
181+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
182+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
183+
* };
184+
*/
185+
class Solution {
186+
public:
187+
int countGreatEnoughNodes(TreeNode* root, int k) {
188+
int ans = 0;
189+
function<priority_queue<int>(TreeNode*)> dfs = [&](TreeNode* root) {
190+
if (!root) {
191+
return priority_queue<int>();
192+
}
193+
auto left = dfs(root->left);
194+
auto right = dfs(root->right);
195+
while (right.size()) {
196+
left.push(right.top());
197+
right.pop();
198+
if (left.size() > k) {
199+
left.pop();
200+
}
201+
}
202+
if (left.size() == k && left.top() < root->val) {
203+
++ans;
204+
}
205+
left.push(root->val);
206+
if (left.size() > k) {
207+
left.pop();
208+
}
209+
return left;
210+
};
211+
dfs(root);
212+
return ans;
213+
}
214+
};
215+
```
216+
217+
### **Go**
218+
219+
```go
220+
/**
221+
* Definition for a binary tree node.
222+
* type TreeNode struct {
223+
* Val int
224+
* Left *TreeNode
225+
* Right *TreeNode
226+
* }
227+
*/
228+
func countGreatEnoughNodes(root *TreeNode, k int) (ans int) {
229+
var dfs func(*TreeNode) hp
230+
dfs = func(root *TreeNode) hp {
231+
if root == nil {
232+
return hp{}
233+
}
234+
l, r := dfs(root.Left), dfs(root.Right)
235+
for _, x := range r.IntSlice {
236+
l.push(x)
237+
if l.Len() > k {
238+
l.pop()
239+
}
240+
}
241+
if l.Len() == k && root.Val > l.IntSlice[0] {
242+
ans++
243+
}
244+
l.push(root.Val)
245+
if l.Len() > k {
246+
l.pop()
247+
}
248+
return l
249+
}
250+
dfs(root)
251+
return
252+
}
253+
254+
type hp struct{ sort.IntSlice }
255+
256+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
257+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
258+
func (h *hp) Pop() interface{} {
259+
a := h.IntSlice
260+
v := a[len(a)-1]
261+
h.IntSlice = a[:len(a)-1]
262+
return v
263+
}
264+
func (h *hp) push(v int) { heap.Push(h, v) }
265+
func (h *hp) pop() int { return heap.Pop(h).(int) }
266+
```
267+
268+
### **...**
269+
270+
```
271+
272+
```
273+
274+
<!-- tabs:end -->

0 commit comments

Comments
 (0)