Skip to content

Commit 3e8c5ba

Browse files
committed
一刷480
1 parent ecc018e commit 3e8c5ba

8 files changed

+135
-23
lines changed

README.adoc

+8-8
Original file line numberDiff line numberDiff line change
@@ -3385,14 +3385,14 @@ TIP: **公众号的微信号是: `jikerizhi`**。__因为众所周知的原因
33853385
//|{doc_base_url}/0479-largest-palindrome-product.adoc[题解]
33863386
//|Hard
33873387
//|
3388-
//
3389-
//|{counter:codes}
3390-
//|{leetcode_base_url}/sliding-window-median/[480. Sliding Window Median^]
3391-
//|{source_base_url}/_0480_SlidingWindowMedian.java[Java]
3392-
//|{doc_base_url}/0480-sliding-window-median.adoc[题解]
3393-
//|Hard
3394-
//|
3395-
//
3388+
3389+
|{counter:codes}
3390+
|{leetcode_base_url}/sliding-window-median/[480. Sliding Window Median^]
3391+
|{source_base_url}/_0480_SlidingWindowMedian.java[Java]
3392+
|{doc_base_url}/0480-sliding-window-median.adoc[题解]
3393+
|Hard
3394+
|
3395+
33963396
//|{counter:codes}
33973397
//|{leetcode_base_url}/magical-string/[481. Magical String^]
33983398
//|{source_base_url}/_0481_MagicalString.java[Java]

docs/0436-find-right-interval.adoc

+17-1
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,27 @@ For [2,3], the interval [3,4] has minimum-"right" start point.
5858

5959
*NOTE:* input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
6060

61-
61+
== 思路分析
6262

6363
[[src-0436]]
64+
[tabs]
65+
====
66+
一刷::
67+
+
68+
--
6469
[{java_src_attr}]
6570
----
6671
include::{sourcedir}/_0436_FindRightInterval.java[tag=answer]
6772
----
73+
--
74+
75+
// 二刷::
76+
// +
77+
// --
78+
// [{java_src_attr}]
79+
// ----
80+
// include::{sourcedir}/_0005_LongestPalindromicSubstring_2.java[tag=answer]
81+
// ----
82+
// --
83+
====
6884

docs/0480-sliding-window-median.adoc

+22-1
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,32 @@ You may assume `k` is always valid, ie: `k` is always smaller than input array's
3939
4040
Answers within `10^-5` of the actual value will be accepted as correct.
4141
42-
42+
== 思路分析
4343
4444
[[src-0480]]
45+
[tabs]
46+
====
47+
一刷::
48+
+
49+
--
4550
[{java_src_attr}]
4651
----
4752
include::{sourcedir}/_0480_SlidingWindowMedian.java[tag=answer]
4853
----
54+
--
55+
56+
// 二刷::
57+
// +
58+
// --
59+
// [{java_src_attr}]
60+
// ----
61+
// include::{sourcedir}/_0005_LongestPalindromicSubstring_2.java[tag=answer]
62+
// ----
63+
// --
64+
====
65+
66+
== 参考资料
67+
68+
. https://leetcode.cn/problems/sliding-window-median/solutions/588643/hua-dong-chuang-kou-zhong-wei-shu-by-lee-7ai6/[480. 滑动窗口中位数 - 官方题解^]
69+
. https://leetcode.cn/problems/sliding-window-median/solutions/589561/xiang-jie-po-su-jie-fa-you-xian-dui-lie-mo397/[480. 滑动窗口中位数 - 详解「朴素解法」&「优先队列 」^]
4970

docs/index.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ include::0462-minimum-moves-to-equal-array-elements-ii.adoc[leveloffset=+1]
10341034

10351035
// include::0479-largest-palindrome-product.adoc[leveloffset=+1]
10361036

1037-
// include::0480-sliding-window-median.adoc[leveloffset=+1]
1037+
include::0480-sliding-window-median.adoc[leveloffset=+1]
10381038

10391039
// include::0481-magical-string.adoc[leveloffset=+1]
10401040

logbook/202406.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,11 @@
429429
|{doc_base_url}/0295-find-median-from-data-stream.adoc[题解]
430430
|双堆思路太妙了!
431431

432+
|{counter:codes}
433+
|{leetcode_base_url}/sliding-window-median/[480. Sliding Window Median^]
434+
|{doc_base_url}/0480-sliding-window-median.adoc[题解]
435+
|双端队列+滑动窗口
436+
432437
|===
433438

434439
截止目前,本轮练习一共完成 {codes} 道题。

src/main/java/com/diguage/algo/leetcode/_0295_FindMedianFromDataStream.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@ public class _0295_FindMedianFromDataStream {
1010
* @since 2024-08-29 20:43:20
1111
*/
1212
class MedianFinder {
13-
Queue<Integer> big;
14-
Queue<Integer> small;
13+
Queue<Integer> topSmall;
14+
Queue<Integer> topLarge;
1515

1616
public MedianFinder() {
1717
// 小顶堆,顶部是最小的。保存较大的一半
18-
big = new PriorityQueue<>();
18+
topSmall = new PriorityQueue<>();
1919
// 大顶堆,顶部是最大的。保存较小的一半
20-
small = new PriorityQueue<>((a, b) -> b - a);
20+
topLarge = new PriorityQueue<>((a, b) -> b - a);
2121
}
2222

2323
public void addNum(int num) {
24-
if (big.size() != small.size()) {
25-
// 倒腾一下,实际 small 中的元素增加了
26-
big.add(num);
27-
small.add(big.poll());
24+
if (topSmall.size() != topLarge.size()) {
25+
// 倒腾一下,实际 topLarge 中的元素增加了
26+
topSmall.add(num);
27+
topLarge.add(topSmall.poll());
2828
} else {
29-
// 倒腾一下,实际 big 中的元素增加了
30-
small.add(num);
31-
big.add(small.poll());
29+
// 倒腾一下,实际 topSmall 中的元素增加了
30+
topLarge.add(num);
31+
topSmall.add(topLarge.poll());
3232
}
3333
}
3434

3535
public double findMedian() {
36-
return big.size() != small.size() ? big.peek() : (big.peek() + small.peek()) / 2.0;
36+
return topSmall.size() != topLarge.size() ? topSmall.peek() : (topSmall.peek() + topLarge.peek()) / 2.0;
3737
}
3838
}
3939
// end::answer[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _0436_FindRightInterval {
4+
// tag::answer[]
5+
/**
6+
* @author D瓜哥 · https://www.diguage.com
7+
* @since 2024-08-29 20:49:07
8+
*/
9+
// end::answer[]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.PriorityQueue;
4+
import java.util.Queue;
5+
6+
public class _0480_SlidingWindowMedian {
7+
// tag::answer[]
8+
9+
/**
10+
* 答案是正确的,超大数组测试时,超时了。
11+
*
12+
* @author D瓜哥 · https://www.diguage.com
13+
* @since 2024-08-30 11:45:50
14+
*/
15+
public double[] medianSlidingWindow(int[] nums, int k) {
16+
// 如果窗口是奇数,则 topSmall 多一个
17+
Queue<Integer> topSmall = new PriorityQueue<>((a, b) -> Integer.compare(a, b));
18+
// 使用 Integer.compare,防止两个最小负数相减时溢出
19+
Queue<Integer> topLarge = new PriorityQueue<>((a, b) -> Integer.compare(b, a));
20+
double[] result = new double[nums.length - k + 1];
21+
for (int i = 0; i < k; i++) {
22+
topSmall.add(nums[i]);
23+
}
24+
for (int i = 0; i < k / 2; i++) {
25+
topLarge.add(topSmall.poll());
26+
}
27+
// 先相处再相加,防止溢出
28+
result[0] = k % 2 == 1 ? 1.0 * topSmall.peek()
29+
: topSmall.peek() / 2.0 + topLarge.peek() / 2.0;
30+
for (int i = k; i < nums.length; i++) {
31+
int num = nums[i];
32+
if (topSmall.peek() <= num) {
33+
topSmall.add(num);
34+
} else {
35+
topLarge.add(num);
36+
}
37+
38+
int delNum = nums[i - k];
39+
if (topSmall.peek() <= delNum) {
40+
topSmall.remove(delNum);
41+
} else {
42+
topLarge.remove(delNum);
43+
}
44+
// 添加,删除,再平衡双堆,这样才能保证堆的平衡性
45+
// topSmall 应该始终大于等于 topLarge
46+
while (topLarge.size() > topSmall.size()) {
47+
topSmall.add(topLarge.poll());
48+
}
49+
// topSmall 与 topLarge 的差值不能大于 1
50+
while (topSmall.size() - topLarge.size() > 1) {
51+
topLarge.add(topSmall.poll());
52+
}
53+
54+
result[i - k + 1] = k % 2 == 1 ? 1.0 * topSmall.peek()
55+
: topSmall.peek() / 2.0 + topLarge.peek() / 2.0;
56+
}
57+
return result;
58+
}
59+
// end::answer[]
60+
}

0 commit comments

Comments
 (0)