Skip to content

Commit 77e008e

Browse files
committed
57
1 parent 58e52ef commit 77e008e

File tree

3 files changed

+215
-2
lines changed

3 files changed

+215
-2
lines changed

SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@
5656
* [53. Maximum Subarray](leetCode-53-Maximum-Subarray.md)
5757
* [54. Spiral Matrix](leetCode-54-Spiral-Matrix.md)
5858
* [55. Jump Game](leetCode-55-Jump-Game.md)
59-
* [56. Merge Intervals](leetCode-56-Merge-Intervals.md)
59+
* [56. Merge Intervals](leetCode-56-Merge-Intervals.md)
60+
* [57. Insert Interval](leetCode-57-Insert-Interval.md)

leetCode-56-Merge-Intervals.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# [题目描述(中等难度)
1+
# 题目描述(中等难度)
22

33
![](https://windliang.oss-cn-beijing.aliyuncs.com/56.jpg)
44

leetCode-57-Insert-Interval.md

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# 题目描述(困难难度)
2+
3+
![](https://windliang.oss-cn-beijing.aliyuncs.com/57.jpg)
4+
5+
[上一道](https://leetcode.windliang.cc/leetCode-56-Merge-Intervals.html)可以说是一个问题,只不过这个是给一个已经合并好的列表,然后给一个新的节点依据规则加入到合并好的列表。
6+
7+
# 解法一
8+
9+
对应 [56 题](https://leetcode.windliang.cc/leetCode-56-Merge-Intervals.html)的解法一,没看的话,可以先过去看一下。这个问题其实就是我们解法中的一个子问题,所以直接加过来就行了。
10+
11+
```java
12+
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
13+
Interval start = null;
14+
Interval end = null;
15+
int i_start = newInterval.start;
16+
int i_end =newInterval.end;
17+
int size = intervals.size();
18+
List<Interval> in = new ArrayList<>();
19+
//遍历合并好的列表
20+
for (int j = 0; j < size; j++) {
21+
if (i_start >= intervals.get(j).start && i_start <= intervals.get(j).end) {
22+
start = intervals.get(j);
23+
}
24+
if (i_end >= intervals.get(j).start && i_end <= intervals.get(j).end) {
25+
end = intervals.get(j);
26+
}
27+
if (i_start < intervals.get(j).start && i_end >intervals.get(j).end) {
28+
in.add(intervals.get(j));
29+
}
30+
31+
}
32+
if (in.size() != 0) {
33+
for (int index = 0; index < in.size(); index++) {
34+
intervals.remove(in.get(index));
35+
}
36+
}
37+
Interval interval = null;
38+
//根据不同的情况,生成新的节点
39+
if (equals(start, end)) {
40+
int s = start == null ? i_start : start.start;
41+
int e = end == null ? i_end : end.end;
42+
interval = new Interval(s, e);
43+
} else if (start!= null && end!=null) {
44+
interval = new Interval(start.start, end.end);
45+
}else if (start == null) {
46+
interval = new Interval(i_start, i_end);
47+
}
48+
if (start != null) {
49+
intervals.remove(start);
50+
}
51+
if (end != null) {
52+
intervals.remove(end);
53+
}
54+
//不同之处是生成的节点,要遍历原节点,根据 start 插入到对应的位置,虽然题目没说,但这里如果不按顺序插入的话,leetcode 过不了。
55+
for(int i = 0;i<intervals.size();i++){
56+
if(intervals.get(i).start>interval.start){
57+
intervals.add(i,interval);
58+
return intervals;
59+
}
60+
}
61+
intervals.add(interval);
62+
return intervals;
63+
}
64+
private boolean equals(Interval start, Interval end) {
65+
if (start == null && end == null) {
66+
return false;
67+
}
68+
if (start == null || end == null) {
69+
return true;
70+
}
71+
if (start.start == end.start && start.end == end.end) {
72+
return true;
73+
}
74+
return false;
75+
}
76+
```
77+
78+
时间复杂度:O(n)。
79+
80+
空间复杂度: O(n), 里边的 in 变量用来存储囊括的节点时候耗费的。
81+
82+
我们其实可以利用迭代器,一边遍历,一边删除,这样就不需要 in 变量了。
83+
84+
```java
85+
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
86+
Interval start = null;
87+
Interval end = null;
88+
int i_start = newInterval.start;
89+
int i_end = newInterval.end;
90+
//利用迭代器遍历
91+
for (Iterator<Interval> it = intervals.iterator(); it.hasNext();) {
92+
Interval inter = it.next();
93+
if (i_start >= inter.start && i_start <= inter.end) {
94+
start = inter;
95+
}
96+
if (i_end >= inter.start && i_end <= inter.end) {
97+
end = inter;
98+
}
99+
if (i_start < inter.start && i_end > inter.end) {
100+
101+
it.remove();
102+
}
103+
}
104+
Interval interval = null;
105+
if (equals(start, end)) {
106+
int s = start == null ? i_start : start.start;
107+
int e = end == null ? i_end : end.end;
108+
interval = new Interval(s, e);
109+
} else if (start != null && end != null) {
110+
interval = new Interval(start.start, end.end);
111+
} else if (start == null) {
112+
interval = new Interval(i_start, i_end);
113+
}
114+
if (start != null) {
115+
intervals.remove(start);
116+
}
117+
if (end != null) {
118+
intervals.remove(end);
119+
}
120+
for (int i = 0; i < intervals.size(); i++) {
121+
if (intervals.get(i).start > interval.start) {
122+
intervals.add(i, interval);
123+
return intervals;
124+
}
125+
}
126+
intervals.add(interval);
127+
return intervals;
128+
}
129+
130+
private boolean equals(Interval start, Interval end) {
131+
if (start == null && end == null) {
132+
return false;
133+
}
134+
if (start == null || end == null) {
135+
return true;
136+
}
137+
if (start.start == end.start && start.end == end.end) {
138+
return true;
139+
}
140+
return false;
141+
}
142+
```
143+
144+
时间复杂度:O(n)。
145+
146+
空间复杂度: O(1)。
147+
148+
# 解法二
149+
150+
对应 [56 题](https://leetcode.windliang.cc/leetCode-56-Merge-Intervals.html)的解法二,考虑到它给定的合并的列表是有序的,和解法二是一个思想。只不过这里不能直接从末尾添加,而是根据新节点的 start 来找到它应该在的位置,然后再利用之前的想法就够了。
151+
152+
这里把 leetcode 里的两种写法,贴过来,大家可以参考一下。
153+
154+
[第一种](https://leetcode.com/problems/insert-interval/discuss/21602/Short-and-straight-forward-Java-solution)
155+
156+
```java
157+
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
158+
List<Interval> result = new LinkedList<>();
159+
int i = 0;
160+
// 将新节点之前的节点加到结果中
161+
while (i < intervals.size() && intervals.get(i).end < newInterval.start)
162+
result.add(intervals.get(i++));
163+
// 和新节点判断是否重叠,更新新节点
164+
while (i < intervals.size() && intervals.get(i).start <= newInterval.end) {
165+
newInterval = new Interval(
166+
Math.min(newInterval.start, intervals.get(i).start),
167+
Math.max(newInterval.end, intervals.get(i).end));
168+
i++;
169+
}
170+
//将新节点加入
171+
result.add(newInterval);
172+
///剩下的全部加进来
173+
while (i < intervals.size()) result.add(intervals.get(i++));
174+
return result;
175+
}
176+
```
177+
178+
[第二种](https://leetcode.com/problems/insert-interval/discuss/21600/Short-java-code)。和之前是一样的思想,只不过更加的简洁,可以参考一下。
179+
180+
```java
181+
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
182+
List<Interval> result = new ArrayList<Interval>();
183+
for (Interval i : intervals) {
184+
//新加的入的节点在当前节点后边
185+
if (newInterval == null || i.end < newInterval.start)
186+
result.add(i);
187+
//新加入的节点在当前节点的前边
188+
else if (i.start > newInterval.end) {
189+
result.add(newInterval);
190+
result.add(i);
191+
newInterval = null;
192+
//新加入的节点和当前节点有重合,更新节点
193+
} else {
194+
newInterval.start = Math.min(newInterval.start, i.start);
195+
newInterval.end = Math.max(newInterval.end, i.end);
196+
}
197+
}
198+
if (newInterval != null)
199+
result.add(newInterval);
200+
return result;
201+
}
202+
```
203+
204+
总的来说,上边两个写法本质是一样的,就是依据他们是有序的,先把新节点前边的节点加入,然后开始判断是否重合,当前节点加入后,把后边的加入就可以了。
205+
206+
时间复杂度:O(n)。
207+
208+
空间复杂度:O(n),存储最后的结果。
209+
210+
#
211+
212+
总的来说,这道题可以看做上道题的一些变形,本质上是一样的。由于用 for 循环不能一边遍历列表,一边删除某个元素,所以利用迭代器实现边遍历,边删除,自己也是第一次用。此外,解法一更加通用些,它不要求给定的列表有序。

0 commit comments

Comments
 (0)