Skip to content

Commit a2c0c66

Browse files
authored
feat: add solutions for lc No.3831 (#5009)
1 parent 7af513f commit a2c0c66

14 files changed

Lines changed: 696 additions & 3 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
- [乘积小于 K 的子数组](/solution/0700-0799/0713.Subarray%20Product%20Less%20Than%20K/README.md) - `双指针`
5353
- [位 1 的个数](/solution/0100-0199/0191.Number%20of%201%20Bits/README.md) - `位运算``lowbit`
5454
- [合并区间](/solution/0000-0099/0056.Merge%20Intervals/README.md) - `区间合并`
55-
<!-- 排序算法、待补充 -->
55+
<!-- 排序算法、待补充 -->
5656

5757
### 2. 数据结构
5858

solution/3000-3099/3013.Divide an Array Into Subarrays With Minimum Cost II/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,6 @@ class TreapMultiSet<T = number> implements ITreapMultiSet<T> {
10081008

10091009
#### Rust
10101010

1011-
10121011
```rust
10131012
use std::collections::BTreeMap;
10141013

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
---
2+
comments: true
3+
difficulty: 中等
4+
edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3831.Median%20of%20a%20Binary%20Search%20Tree%20Level/README.md
5+
---
6+
7+
<!-- problem:start -->
8+
9+
# [3831. Median of a Binary Search Tree Level 🔒](https://leetcode.cn/problems/median-of-a-binary-search-tree-level)
10+
11+
[English Version](/solution/3800-3899/3831.Median%20of%20a%20Binary%20Search%20Tree%20Level/README_EN.md)
12+
13+
## 题目描述
14+
15+
<!-- description:start -->
16+
17+
<p>You are given the <code>root</code> of a <strong>Binary Search Tree (BST)</strong> and an integer <code>level</code>.</p>
18+
19+
<p>The root node is at level 0. Each level represents the distance from the root.</p>
20+
21+
<p>Return the <strong>median value</strong> of all node values present at the given <code>level</code>. If the level does not exist or contains no nodes, return -1.</p>
22+
23+
<p>The <strong>median</strong> is defined as the middle element after sorting the values at that level in <strong>non-decreasing</strong> order. If the number of values at that level is even, return the <strong>upper</strong> median (the larger of the two middle elements after sorting).</p>
24+
25+
<p>&nbsp;</p>
26+
<p><strong class="example">Example 1:</strong></p>
27+
28+
<p><img src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/3800-3899/3831.Median%20of%20a%20Binary%20Search%20Tree%20Level/images/screenshot-2026-01-27-at-20801pm.png" style="width: 180px; height: 182px;" /></p>
29+
30+
<div class="example-block">
31+
<p><strong>Input:</strong> <span class="example-io">root = [4,null,5,null,7], level = 2</span></p>
32+
33+
<p><strong>Output:</strong> <span class="example-io">7</span></p>
34+
35+
<p><strong>Explanation:</strong></p>
36+
37+
<p>The nodes at <code>level = 2</code> are <code>[7]</code>. The median value is 7.</p>
38+
</div>
39+
40+
<p><strong class="example">Example 2:</strong></p>
41+
42+
<p><img src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/3800-3899/3831.Median%20of%20a%20Binary%20Search%20Tree%20Level/images/screenshot-2026-01-27-at-20926pm.png" style="width: 200px; height: 169px;" /></p>
43+
44+
<div class="example-block">
45+
<p><strong>Input:</strong> <span class="example-io">root = [6,3,8], level = 1</span></p>
46+
47+
<p><strong>Output:</strong> <span class="example-io">8</span></p>
48+
49+
<p><strong>Explanation:</strong></p>
50+
51+
<p>The nodes at <code>level = 1</code> are <code>[3, 8]</code>. There are two possible median values, so the larger one 8 is the answer.</p>
52+
</div>
53+
54+
<p><strong class="example">Example 3:</strong></p>
55+
56+
<p><strong class="example">​​​​​​​​​​​​​​</strong><img src="https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/3800-3899/3831.Median%20of%20a%20Binary%20Search%20Tree%20Level/images/screenshot-2026-01-27-at-21001pm.png" style="width: 150px; height: 193px;" /></p>
57+
58+
<div class="example-block">
59+
<p><strong>Input:</strong> <span class="example-io">root = [2,1], level = 2</span></p>
60+
61+
<p><strong>Output:</strong> <span class="example-io">-1</span></p>
62+
63+
<p><strong>Explanation:</strong></p>
64+
65+
<p>There is no node present at <code>level = 2</code>​​​​​​​, so the answer is -1.</p>
66+
</div>
67+
68+
<p>&nbsp;</p>
69+
<p><strong>Constraints:</strong></p>
70+
71+
<ul>
72+
<li>The number of nodes in the tree is in the range <code>[1, 2 * 10<sup>5</sup>]</code>.</li>
73+
<li><code>1 &lt;= Node.val &lt;= 10<sup>6</sup></code></li>
74+
<li><code>0 &lt;= level &lt;= 2 * 10<sup>​​​​​​​5</sup></code></li>
75+
</ul>
76+
77+
<!-- description:end -->
78+
79+
## 解法
80+
81+
<!-- solution:start -->
82+
83+
### 方法一:DFS
84+
85+
我们注意到,题目要求我们找到二叉搜索树中某一层的节点值的中位数。由于中位数的定义是将节点值排序后取中间的值,而二叉搜索树的中序遍历本身就是有序的,因此我们可以通过中序遍历来收集指定层级的节点值。
86+
87+
我们定义一个辅助函数 $\text{dfs}(root, i)$,其中 $root$ 是当前节点,而 $i$ 是当前节点的层级。在函数中,如果当前节点为空,则直接返回。否则,我们递归地遍历左子树,检查当前节点的层级是否等于目标层级,如果是,则将当前节点的值加入结果列表中,最后递归地遍历右子树。
88+
89+
我们初始化一个空列表 $\text{nums}$ 来存储指定层级的节点值,并调用 $\text{dfs}(root, 0)$ 来开始遍历。最后,我们检查 $\text{nums}$ 是否为空,如果为空则返回 -1,否则返回 $\text{nums}$ 中间位置的值。
90+
91+
时间复杂度 $O(n)$,空间复杂度 $O(n)$,其中 $n$ 是树中节点的数量。
92+
93+
<!-- tabs:start -->
94+
95+
#### Python3
96+
97+
```python
98+
# Definition for a binary tree node.
99+
# class TreeNode:
100+
# def __init__(self, val=0, left=None, right=None):
101+
# self.val = val
102+
# self.left = left
103+
# self.right = right
104+
class Solution:
105+
def levelMedian(self, root: Optional[TreeNode], level: int) -> int:
106+
def dfs(root: Optional[TreeNode], i: int):
107+
if root is None:
108+
return
109+
dfs(root.left, i + 1)
110+
if i == level:
111+
nums.append(root.val)
112+
dfs(root.right, i + 1)
113+
114+
nums = []
115+
dfs(root, 0)
116+
return nums[len(nums) // 2] if nums else -1
117+
```
118+
119+
#### Java
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 List<Integer> nums = new ArrayList<>();
139+
private int level;
140+
141+
public int levelMedian(TreeNode root, int level) {
142+
this.level = level;
143+
dfs(root, 0);
144+
return nums.isEmpty() ? -1 : nums.get(nums.size() / 2);
145+
}
146+
147+
private void dfs(TreeNode root, int i) {
148+
if (root == null) {
149+
return;
150+
}
151+
dfs(root.left, i + 1);
152+
if (i == level) {
153+
nums.add(root.val);
154+
}
155+
dfs(root.right, i + 1);
156+
}
157+
}
158+
```
159+
160+
#### C++
161+
162+
```cpp
163+
/**
164+
* Definition for a binary tree node.
165+
* struct TreeNode {
166+
* int val;
167+
* TreeNode *left;
168+
* TreeNode *right;
169+
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
170+
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
171+
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
172+
* };
173+
*/
174+
class Solution {
175+
public:
176+
int levelMedian(TreeNode* root, int level) {
177+
vector<int> nums;
178+
179+
auto dfs = [&](this auto&& dfs, TreeNode* node, int i) -> void {
180+
if (!node) {
181+
return;
182+
}
183+
dfs(node->left, i + 1);
184+
if (i == level) {
185+
nums.push_back(node->val);
186+
}
187+
dfs(node->right, i + 1);
188+
};
189+
190+
dfs(root, 0);
191+
return nums.empty() ? -1 : nums[nums.size() / 2];
192+
}
193+
};
194+
```
195+
196+
#### Go
197+
198+
```go
199+
/**
200+
* Definition for a binary tree node.
201+
* type TreeNode struct {
202+
* Val int
203+
* Left *TreeNode
204+
* Right *TreeNode
205+
* }
206+
*/
207+
func levelMedian(root *TreeNode, level int) int {
208+
nums := make([]int, 0)
209+
210+
var dfs func(*TreeNode, int)
211+
dfs = func(node *TreeNode, i int) {
212+
if node == nil {
213+
return
214+
}
215+
dfs(node.Left, i+1)
216+
if i == level {
217+
nums = append(nums, node.Val)
218+
}
219+
dfs(node.Right, i+1)
220+
}
221+
222+
dfs(root, 0)
223+
if len(nums) == 0 {
224+
return -1
225+
}
226+
return nums[len(nums)/2]
227+
}
228+
```
229+
230+
#### TypeScript
231+
232+
```ts
233+
/**
234+
* Definition for a binary tree node.
235+
* class TreeNode {
236+
* val: number
237+
* left: TreeNode | null
238+
* right: TreeNode | null
239+
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
240+
* this.val = (val===undefined ? 0 : val)
241+
* this.left = (left===undefined ? null : left)
242+
* this.right = (right===undefined ? null : right)
243+
* }
244+
* }
245+
*/
246+
function levelMedian(root: TreeNode | null, level: number): number {
247+
const nums: number[] = [];
248+
249+
const dfs = (node: TreeNode | null, i: number): void => {
250+
if (node === null) {
251+
return;
252+
}
253+
dfs(node.left, i + 1);
254+
if (i === level) {
255+
nums.push(node.val);
256+
}
257+
dfs(node.right, i + 1);
258+
};
259+
260+
dfs(root, 0);
261+
if (nums.length === 0) {
262+
return -1;
263+
}
264+
return nums[nums.length >> 1];
265+
}
266+
```
267+
268+
<!-- tabs:end -->
269+
270+
<!-- solution:end -->
271+
272+
<!-- problem:end -->

0 commit comments

Comments
 (0)