題目:
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]
Example 2:
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
解法1:
首先考慮本題中列表是有序的
首先考慮newInterval 的最小值都大於intervals中某個列表的最大值,這樣我們只需要先加入intervals 中的列表即可
另一種情況newInterval 的最大值都小於intervals中某個列表的最小值,這樣我們只需要先加入newInterval
如果newInterval 的最大值都大於等於intervals中某個列表的最小值,這時候我們需要合併列表
新列表的最小值是兩者中的最小值,新列表的最大值是兩者中的最大值,然後繼續循環,看是否滿足合併條件(newInterval 的最大值都大於等於intervals中某個列表的最小值)
最後我們需要查看intervals的列表是否添加完,如果沒有添加intervals中的剩餘列表
例:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
cur 指向intervals列表的下標,初始爲0
首先第一個列表的最大值都小於newInterval,說明我們需要將它添到我們的結果中res = [[1,2]]
第二個列表不滿足該循環條件,檢查是否滿足合併條件newInterval 的最大值都大於等於intervals中某個列表的最小值,3 <= 8
合併列表:最小值爲兩者中的最小值3,最大值爲兩者中的最大值8 [3,8]
然後繼續查看第三個列表和新的列表是否滿足合併條件,6 <= 8
合併列表:最小值爲兩者中的最小值3,最大值爲兩者中的最大值8 [3,8]
然後繼續查看第四個列表和新的列表是否滿足合併條件,8 <= 8
合併列表:最小值爲兩者中的最小值3,最大值爲兩者中的最大值10 [3,10]
然後繼續查看第四個列表和新的列表不滿足合併條件,12 > 10
這時候需要將我們的合併的列表加入到結果集中 res = [[1,2],[3,10]]
最後我們需要查看intervals的列表是否添加完,如果沒有添加intervals中的剩餘列表res = [[1,2],[3,10],[12,16]]
C++:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> res;
int n = intervals.size();
int cur = 0;
while(cur < n && intervals[cur][1] < newInterval[0]){
res.push_back(intervals[cur++]);
}
while(cur < n && intervals[cur][0] <= newInterval[1]){
newInterval[0] = min(intervals[cur][0],newInterval[0]);
newInterval[1] = max(intervals[cur][1],newInterval[1]);
cur++;
}
res.push_back(newInterval);
while(cur < n){
res.push_back(intervals[cur++]);
}
return res;
}
};
java:
最開始的版本方法簽名是list,但是最新的代碼改成了int[][],與list相比,我們不好確定二維數組的初始大小,因爲它插入後數目可能不變,因爲合併了列表,也有可能增加了一個,沒有合併列表,所以我們還是採用List<int[]>,最後返回時再通過 return res.toArray(new int[res.size()][]);轉成二維數組
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> res = new ArrayList<>();
int n = intervals.length;
int cur = 0;
while(cur < n && intervals[cur][1] < newInterval[0]){
res.add(intervals[cur++]);
}
while(cur < n && intervals[cur][0] <= newInterval[1]){
newInterval[0] = Math.min(intervals[cur][0],newInterval[0]);
newInterval[1] = Math.max(intervals[cur][1],newInterval[1]);
cur++;
}
res.add(newInterval);
while(cur < n){
res.add(intervals[cur++]);
}
return res.toArray(new int[res.size()][]);
}
}
class Solution(object):
def insert(self, intervals, newInterval):
"""
:type intervals: List[List[int]]
:type newInterval: List[int]
:rtype: List[List[int]]
"""
cur = 0
res = []
n = len(intervals)
while cur < n and intervals[cur][1] < newInterval[0]:
res.append(intervals[cur])
cur += 1
while cur < n and intervals[cur][0] <= newInterval[1]:
newInterval[0] = min(intervals[cur][0],newInterval[0])
newInterval[1] = max(intervals[cur][1],newInterval[1])
cur += 1
res.append(newInterval)
while cur < n:
res.append(intervals[cur])
cur += 1
return res;
解法2:
與解法1類似
這次我們遍歷intervals,與解法1不同,用i記錄intervals的位置,用cur記錄插入的位置
首先考慮newInterval 的最小值都大於intervals中某個列表的最大值,這樣我們只需要先加入intervals 中的列表即可,插入的位置要更新
另一種情況newInterval 的最大值都小於intervals中某個列表的最小值,這樣我們只需要先加入intervals中的列表即可,此時插入的位置已經固定了
如果newInterval 的最大值都大於等於intervals中某個列表的最小值,這時候我們需要合併列表
遍歷完成後,根據插入的位置加入newInterval
c++:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> res;
int n = intervals.size();
int cur = 0;
for(int i = 0; i < n; i++){
if(intervals[i][1] < newInterval[0]){
res.push_back(intervals[i]);
cur++;
} else if(intervals[i][0] > newInterval[1]){
res.push_back(intervals[i]);
} else{
newInterval[0] = min(intervals[i][0],newInterval[0]);
newInterval[1] = max(intervals[i][1],newInterval[1]);
}
}
res.insert(res.begin() + cur,newInterval);
return res;
}
};
java:
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> res = new ArrayList<>();
int n = intervals.length;
int cur = 0;
for(int i = 0; i < n; i++){
if(intervals[i][1] < newInterval[0]){
res.add(intervals[i]);
cur++;
} else if(intervals[i][0] > newInterval[1]){
res.add(intervals[i]);
} else{
newInterval[0] = Math.min(intervals[i][0],newInterval[0]);
newInterval[1] = Math.max(intervals[i][1],newInterval[1]);
}
}
res.add(cur,newInterval);
return res.toArray(new int[res.size()][]);
}
}
python:
class Solution(object):
def insert(self, intervals, newInterval):
"""
:type intervals: List[List[int]]
:type newInterval: List[int]
:rtype: List[List[int]]
"""
cur = 0
res = []
for interval in intervals:
if interval[1] < newInterval[0]:
res.append(interval)
cur += 1
elif interval[0] > newInterval[1]:
res.append(interval)
else:
newInterval[0] = min(interval[0],newInterval[0])
newInterval[1] = max(interval[1],newInterval[1])
res.insert(cur, newInterval)
return res