Skip to content

Commit 5413682

Browse files
committed
二刷56
1 parent c8f037d commit 5413682

File tree

6 files changed

+103
-28
lines changed

6 files changed

+103
-28
lines changed

docs/0000-04-merge-intervals.adoc

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
= Merge Intervals 区间合并
33

44

5-
区间合并模式是一个用来处理有区间重叠的很高效的技术。在设计到区间的很多问题中,通常咱们需要要么判断是否有重叠,要么合并区间,如果他们重叠的话。这个模式是这么起作用的
5+
区间合并模式是一个用来处理有区间重叠的很高效的技术。在涉及到区间的很多问题中,通常咱们需要要么判断是否有重叠,要么合并区间,如果他们重叠的话。这个模式是这么起作用的
66

7-
给两个区间,一个是a,另外一个是b。别小看就两个区间,他们之间的关系能跑出来6种情况。详细的就看图啦。
7+
给两个区间,一个是 a,另外一个是 b。别小看就两个区间,他们之间的关系能跑出来6种情况。详细的就看图啦。
8+
9+
image::images/0056-01.png[{image_attr}]
810

911
怎么识别啥时候用合并区间模式呀?
1012

docs/0056-merge-intervals.adoc

+53-18
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,70 @@
11
[#0056-merge-intervals]
2-
= 56. Merge Intervals
2+
= 56. 合并区间
33

4-
{leetcode}/problems/merge-intervals/[LeetCode - Merge Intervals^]
4+
https://leetcode.cn/problems/merge-intervals/[LeetCode - 56. 合并区间 ^]
55

6-
Given a collection of intervals, merge all overlapping intervals.
6+
以数组 `intervals` 表示若干个区间的集合,其中单个区间为 `+intervals[i] = [start+`~`+i+`~`+, end+`~`+i+`~`+]+`。请你合并所有重叠的区间,并返回 _一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间_
77

8-
*Example 1:*
98

10-
[subs="verbatim,quotes,macros"]
11-
----
12-
*Input:* [[1,3],[2,6],[8,10],[15,18]]
13-
*Output:* [[1,6],[8,10],[15,18]]
14-
*Explanation:* Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
9+
*示例 1:*
1510

16-
----
11+
....
12+
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
13+
输出:[[1,6],[8,10],[15,18]]
14+
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
15+
....
1716

18-
*Example 2:*
17+
*示例 2:*
1918

20-
[subs="verbatim,quotes,macros"]
21-
----
22-
*Input:* [[1,4],[4,5]]
23-
*Output:* [[1,5]]
24-
*Explanation:* Intervals [1,4] and [4,5] are considered overlapping.
25-
----
19+
....
20+
输入:intervals = [[1,4],[4,5]]
21+
输出:[[1,5]]
22+
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
23+
....
24+
25+
26+
*提示:*
27+
28+
* `+1 <= intervals.length <= 10+`^`+4+`^
29+
* `+intervals[i].length == 2+`
30+
* `+0 <= start+`~`+i+`~`+<= end+`~`+i+`~`+<= 10+`^`+4+`^
31+
32+
33+
34+
== 思路分析
2635

27-
*NOTE:* input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
36+
在没有排序之前,两个区间有六种关系:
37+
38+
image::images/0056-01.png[{image_attr}]
39+
40+
观察这六种排序,明显后三种排序是前三种排序的一个“变种”:对区间根据起点和终点进行排序,就是剩下前三种排序了。再对其进行合并就很简单了:
41+
42+
. 没有重叠,则直接开启新区间。
43+
. 有重叠,起点和终点分别取最大值和最小值即可:由于区间已经排序,则相邻两个区间的起点是前面区间的起点,重点则是两个区间终点的最大值。
2844

2945

3046
[[src-0056]]
47+
[tabs]
48+
====
49+
一刷::
50+
+
51+
--
3152
[{java_src_attr}]
3253
----
3354
include::{sourcedir}/_0056_MergeIntervals.java[tag=answer]
3455
----
56+
--
57+
58+
二刷::
59+
+
60+
--
61+
[{java_src_attr}]
62+
----
63+
include::{sourcedir}/_0056_MergeIntervals_2.java[tag=answer]
64+
----
65+
--
66+
====
67+
68+
69+
== 参考资料
3570

docs/images/0056-01.png

66.6 KB
Loading

logbook/202503.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ endif::[]
2525
|{doc_base_url}/0033-search-in-rotated-sorted-array.adoc[题解]
2626
|⭕️ 重点去处理有序部分,在有序部分内查找不到,则去另外一部分去查找。
2727

28+
|{counter:codes2503}
29+
|{leetcode_base_url}/merge-intervals/[56. Merge Intervals^]
30+
|{doc_base_url}/0056-merge-intervals.adoc[题解]
31+
|✅ 对区间进行排序,然后快慢指针在当前数组上对其进行合并。
32+
2833
|===
2934

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

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

+6-8
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@
3535
* @since 2019-10-23 12:27
3636
*/
3737
public class _0056_MergeIntervals {
38-
// tag::answer[]
39-
40-
/**
41-
* @author D瓜哥 · https://www.diguage.com
42-
* @since 2019-10-23 12:27
43-
*/
38+
// tag::answer[]
39+
/**
40+
* @author D瓜哥 · https://www.diguage.com
41+
* @since 2019-10-23 12:27
42+
*/
4443
public int[][] merge(int[][] intervals) {
4544
if (Objects.isNull(intervals) || intervals.length <= 1) {
4645
return intervals;
@@ -57,8 +56,7 @@ public int[][] merge(int[][] intervals) {
5756
}
5857
return Arrays.copyOf(intervals, index + 1);
5958
}
60-
61-
// end::answer[]
59+
// end::answer[]
6260

6361

6462
public static void main(String[] args) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.Arrays;
4+
import java.util.Comparator;
5+
6+
public class _0056_MergeIntervals_2 {
7+
// tag::answer[]
8+
/**
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-03-05 17:14:39
11+
*/
12+
public int[][] merge(int[][] intervals) {
13+
// 对待合并区间进行排序,首先按照起点排序,然后按终点排序
14+
// 排序后,可以保证起点有序;在起点相等时,终点有序。
15+
Arrays.sort(intervals, Comparator.comparingInt((int[] o) -> o[0])
16+
.thenComparingInt(o -> o[1]));
17+
int merged = 0, curr = 0;
18+
while (merged < intervals.length && curr < intervals.length) {
19+
if (intervals[curr][0] <= intervals[merged][1]) {
20+
// 如果当前区间起点小于等于合并后区间的终点,那么直接合并到已经合并的区间里
21+
intervals[merged][1] = Math.max(intervals[merged][1], intervals[curr][1]);
22+
} else {
23+
// 如果当前区间起点大于合并后区间的终点,那么直接开启新的合并区间
24+
merged++;
25+
intervals[merged] = intervals[curr];
26+
}
27+
// 每次合并,当前区间都要向前走一下。
28+
curr++;
29+
}
30+
// 从数组中复制出已经合并了的区间
31+
return Arrays.copyOf(intervals, merged + 1);
32+
}
33+
34+
// end::answer[]
35+
}

0 commit comments

Comments
 (0)