Skip to content

Commit 8a91d09

Browse files
committed
三刷295
1 parent c6a3820 commit 8a91d09

File tree

3 files changed

+113
-27
lines changed

3 files changed

+113
-27
lines changed

docs/0295-find-median-from-data-stream.adoc

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,43 @@
11
[#0295-find-median-from-data-stream]
2-
= 295. Find Median from Data Stream
2+
= 295. 数据流的中位数
33

4-
{leetcode}/problems/find-median-from-data-stream/[LeetCode - Find Median from Data Stream^]
4+
https://leetcode.cn/problems/find-median-from-data-stream/[LeetCode - 295. 数据流的中位数 ^]
55

6-
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.
7-
For example,
6+
**中位数**是有序整数列表中的中间值。如果列表的大小是偶数,则没有中间值,中位数是两个中间值的平均值。
87

9-
`[2,3,4]`, the median is `3`
8+
* 例如 `arr = [2,3,4]` 的中位数是 `3`
9+
* 例如 `arr = [2,3]` 的中位数是 `(2 + 3) / 2 = 2.5`
1010
11-
`[2,3]`, the median is `(2 + 3) / 2 = 2.5`
11+
实现 MedianFinder 类:
1212

13-
Design a data structure that supports the following two operations:
13+
* `MedianFinder()` 初始化 `MedianFinder` 对象。
14+
* `void addNum(int num)` 将数据流中的整数 `num` 添加到数据结构中。
15+
* `double findMedian()` 返回到目前为止所有元素的中位数。与实际答案相差 `10^-5^` 以内的答案将被接受。
1416
17+
*示例 1:*
1518

16-
* void addNum(int num) - Add a integer number from the data stream to the data structure.
17-
* double findMedian() - Return the median of all elements so far.
19+
....
20+
输入
21+
["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"]
22+
[[], [1], [2], [], [3], []]
23+
输出
24+
[null, null, null, 1.5, null, 2.0]
1825
26+
解释
27+
MedianFinder medianFinder = new MedianFinder();
28+
medianFinder.addNum(1); // arr = [1]
29+
medianFinder.addNum(2); // arr = [1, 2]
30+
medianFinder.findMedian(); // 返回 1.5 ((1 + 2) / 2)
31+
medianFinder.addNum(3); // arr[1, 2, 3]
32+
medianFinder.findMedian(); // return 2.0
33+
....
1934

20-
35+
*提示:*
2136

22-
*Example:*
37+
* `-10^5^ \<= num \<= 10^5^`
38+
* 在调用 `findMedian` 之前,数据结构中至少有一个元素
39+
* 最多 `5 * 10^4^` 次调用 `addNum``findMedian`
2340
24-
[subs="verbatim,quotes,macros"]
25-
----
26-
addNum(1)
27-
addNum(2)
28-
findMedian() -> 1.5
29-
addNum(3)
30-
findMedian() -> 2
31-
----
32-
33-
34-
35-
*Follow up:*
36-
37-
38-
* If all integer numbers from the stream are between 0 and 100, how would you optimize it?
39-
* If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?
4041
4142
== 思路分析
4243

@@ -89,6 +90,15 @@ include::{sourcedir}/_0295_FindMedianFromDataStream.java[tag=answer]
8990
include::{sourcedir}/_0295_FindMedianFromDataStream_2.java[tag=answer]
9091
----
9192
--
93+
94+
三刷::
95+
+
96+
--
97+
[{java_src_attr}]
98+
----
99+
include::{sourcedir}/_0295_FindMedianFromDataStream_3.java[tag=answer]
100+
----
101+
--
92102
====
93103

94104
== 参考资料

logbook/202503.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ endif::[]
8080
|{doc_base_url}/0041-first-missing-positive.adoc[题解]
8181
|⭕️ 循环排序,看了答案,自己写出来了。
8282

83+
|{counter:codes2503}
84+
|{leetcode_base_url}/find-median-from-data-stream/[295. Find Median from Data Stream^]
85+
|{doc_base_url}/0295-find-median-from-data-stream.adoc[题解]
86+
|⭕️ 双堆,思路理解,写代码却有很多问题。
87+
8388
|===
8489

8590
截止目前,本轮练习一共完成 {codes2503} 道题。
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.PriorityQueue;
4+
5+
public class _0295_FindMedianFromDataStream_3 {
6+
// tag::answer[]
7+
8+
/**
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-03-28 18:53:57
11+
*/
12+
class MedianFinder {
13+
// 小顶堆,顶部是最小的。保存较大的一半
14+
PriorityQueue<Integer> topSmall;
15+
// 大顶堆,顶部是最大的。保存较小的一半
16+
PriorityQueue<Integer> topLarge;
17+
18+
public MedianFinder() {
19+
topSmall = new PriorityQueue<>();
20+
// 注意:这里的 Comparator 是反向,不能直接用 Integer::compare 代替
21+
topLarge = new PriorityQueue<>((a, b) -> Integer.compare(b, a));
22+
}
23+
24+
public void addNum(int num) {
25+
if (topSmall.size() == topLarge.size()) {
26+
topLarge.offer(num);
27+
topSmall.offer(topLarge.poll());
28+
} else {
29+
topSmall.offer(num);
30+
topLarge.offer(topSmall.poll());
31+
}
32+
}
33+
34+
public double findMedian() {
35+
return topSmall.size() == topLarge.size()
36+
? (topSmall.peek() + topLarge.peek()) / 2.0 : topSmall.peek();
37+
}
38+
}
39+
40+
// end::answer[]
41+
public MedianFinder newInstance() {
42+
return new MedianFinder();
43+
}
44+
45+
public static void main(String[] args) {
46+
_0295_FindMedianFromDataStream_3 instance = new _0295_FindMedianFromDataStream_3();
47+
MedianFinder finder = instance.newInstance();
48+
finder.addNum(6);
49+
System.out.println(finder.findMedian());
50+
finder.addNum(10);
51+
System.out.println(finder.findMedian());
52+
finder.addNum(2);
53+
System.out.println(finder.findMedian());
54+
finder.addNum(6);
55+
System.out.println(finder.findMedian());
56+
finder.addNum(5);
57+
System.out.println(finder.findMedian());
58+
finder.addNum(0);
59+
System.out.println(finder.findMedian());
60+
finder.addNum(6);
61+
System.out.println(finder.findMedian());
62+
finder.addNum(3);
63+
System.out.println(finder.findMedian());
64+
finder.addNum(1);
65+
System.out.println(finder.findMedian());
66+
finder.addNum(0);
67+
System.out.println(finder.findMedian());
68+
finder.addNum(0);
69+
System.out.println(finder.findMedian());
70+
}
71+
}

0 commit comments

Comments
 (0)