Open azl397985856 opened 2 years ago
Explanation
Code
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if len(intervals) == 0:
return 0
intervals.sort()
ans = 1
def lenOfLIS(l):
d = []
for start, end in l:
i = bisect.bisect_left(d, end)
if i < len(d):
d[i] = end
elif not d or d[-1] <= start:
d.append(end)
return len(d)
return len(intervals) - lenOfLIS(intervals)
Complexity
贪心
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[1] - interval2[1];
}
});
int n = intervals.length;
int ans = 1;
int r = intervals[0][1];
for (int i = 1; i < n; ++i) {
if(intervals[i][0]>=r){
r = intervals[i][1];
ans++;
}
}
return n - ans;
}
}
思路: since the start of an interval must be smaller or equal to the end of the interval, sort all intervals by each start (or end, both works), then iterate through the input array and record the number of non-overlapping intervals
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// sort the intervals based on its end, increasing order
Arrays.sort(intervals, Comparator.comparingInt(interval -> interval[0]));
int start = intervals[intervals.length-1][0];
// the number of non-overlapping intervals
int count = 1;
for (int i = intervals.length - 1; i >= 0; i--) {
int[] interval = intervals[i];
// non-overlapping case
if (interval[1] <= start) {
start = interval[0];
count++;
}
}
return intervals.length - count;
}
}
Time Complexity: O(nlogn) Space Complexity: O(1)
思路: 贪心, 本题求最小移除的重叠区间, 可转化为求最多保留的不重叠区间数,按照右边界排序,比较连续两个区间,前面一个区间的右边界和相邻后面一个区间的左边界不重叠则保留,最后将总的区间数-最大保留的区间数
复杂度分析:
代码(C++):
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
int n = intervals.size();
if (n == 0) return 0;
sort(intervals.begin(), intervals.end(),
[](const vector<int>& a, const vector<int>& b) { return a[1] < b[1]; }
);
int curR = intervals[0][1];
int maxKeep = 1;
for (int i = 1; i < n; ++i) {
if (intervals[i][0] >= curR) {
maxKeep++;
curR = intervals[i][1];
}
}
return n - maxKeep;
}
};
Greedy. First sort the array by starting time, go through the array, if we find an overlap, remove the one with bigger end time.
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort()
start = float(-inf)
count = 0
for i in intervals:
if i[0] >= start:
start = i[1]
else:
count += 1
start = min(start, i[1])
return count
Greedy approach by ending point
使用语言:Python3
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if len(intervals) == 0:
return 0
intervals.sort()
end = intervals[0][1]
pointer = 0
count = 0
for i in range(1, len(intervals)):
if intervals[pointer][1] > intervals[i][0]:
if intervals[pointer][1] > intervals[i][1]:
pointer = i
count += 1
else:
pointer = i
return count
复杂度分析 时间复杂度:O(nlogn) 空间复杂度:O(1)
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
int n = intervals.length;
int[] f = new int[n];
Arrays.fill(f, 1);
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (intervals[j][1] <= intervals[i][0]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
return n - Arrays.stream(f).max().getAsInt();
}
}
时间复杂度:O(nlogn) 空间复杂度:O(1)
排序+贪心
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
lens={}
starts=[]
ends=[]
s=0
alls=0
for i in intervals:
tp=tuple(i)
len=i[1]-i[0]
lens[tp]=i[1]
starts.append(i[0])
ends.append(i[1])
alls+=1
l=sorted(lens.items(),key=lambda x:x[1])
min_val=min(starts)
s=max(ends)-min_val+1
zeros=[0]*s
c=0
for i in l:
x=i[0][0]
y=i[0][1]
lst=zeros[x-min_val:y-min_val]
if 1 not in lst:
c+=1
for j in range(x,y):
t=j-min_val
zeros[t]=1
return alls-c
排序+贪心
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length <= 1) return 0;
Arrays.sort(intervals , (a , b) ->{
return a[1] - b[1];
});
int end = intervals[0][1];
int sum = 1;
for(int i = 1 ;i < intervals.length ; i++){
if(intervals[i][0] >= end){
sum++;
end = intervals[i][1];
}
}
return intervals.length - sum;
}
}
时间复杂度:O(nlogn) 空间复杂度:O(1)
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) {
return 0;
}
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
return u[1] < v[1];
});
int n = intervals.size();
int right = intervals[0][1];
int ans = 1;
for (int i = 1; i < n; ++i) {
if (intervals[i][0] >= right) {
++ans;
right = intervals[i][1];
}
}
return n - ans;
}
};
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
nums = sorted(intervals, key=lambda x:x[1])
count = 1
end = nums[0][1]
for st, en in nums:
if st >= end:
count += 1
end = en
return len(nums) - count
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
nums = sorted(intervals, key=lambda x:x[1])
count = 1
end = nums[0][1]
for st, en in nums:
if st >= end:
count += 1
end = en
return len(nums) - count
贪心
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
int end = intervals[0][1], remove = 0;
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < end) {
remove++;
end = Math.min(end, intervals[i][1]);
} else {
end = intervals[i][1];
}
}
return remove;
}
}
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
int end = intervals[0][1], count = 1;
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] >= end) {
count++;
end = intervals[i][1];
}
}
return intervals.length - count;
}
}
class Solution { public int eraseOverlapIntervals(int[][] intervals) { if (intervals.length == 0) { return 0; }
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
int n = intervals.length;
int[] f = new int[n];
Arrays.fill(f, 1);
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (intervals[j][1] <= intervals[i][0]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
return n - Arrays.stream(f).max().getAsInt();
}
}
func eraseOverlapIntervals(intervals [][]int) int {
// 本身为空,需要移除0个
n := len(intervals)
if n == 0{
return 0
}
// 根据第二维进行排序, 从小到大
sort.Slice(intervals, func(i, j int) bool{ return intervals[i][1] < intervals[j][1]})
ans, right := 1, intervals[0][1]
for _, p := range intervals[1:]{
if p[0] >= right {
ans++
right = p[1]
}
}
return n - ans
}
title: "Day 67 435. 无重叠区间" date: 2021-11-14T20:25:06+08:00 tags: ["Leetcode", "c++", "Greed"] categories: ["91-day-algorithm"] draft: true
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 1:
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:
输入: [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:
输入: [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
- 1、单刀直入,按照右边界排序,值越大越在后面,而后按照每一个子vector元素的右边界值与失分产生重叠来删除区间即可
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
int n = intervals.size();
if(n == 0) return n;
sort(intervals.begin(), intervals.end(), [](const auto & a, const auto &b)
{
return a[1] < b[1];
});
int del = 0;
int r = intervals[0][1];
for(int i = 1; i < n; i++)
{
if(intervals[i][0] < r) del++;
else r = intervals[i][1];
}
return del;
}
};
时间复杂度:O(nlogn)
空间复杂度:O(logn)
var eraseOverlapIntervals = function(intervals) {
if(intervals.length === 0) return 0;
intervals.sort((interval1, interval2) => {
return parseInt(interval1[1]) - parseInt(interval2[1]);
});
let interval = intervals[0];
const res = [interval];
for(let i = 1; i < intervals.length; i++) {
if(intervals[i][0] >= interval[1]) {
res.push(intervals[i]);
interval = intervals[i];
}
}
return intervals.length - res.length;
};
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
int n = intervals.length;
int[] f = new int[n];
Arrays.fill(f, 1);
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (intervals[j][1] <= intervals[i][0]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
return n - Arrays.stream(f).max().getAsInt();
}
}
var eraseOverlapIntervals = function(intervals) {
let ans = 1
intervals.sort((a, b) => a[1] - b[1])
let right = intervals[0][1]
for (let i = 1; i < intervals.length; i++) {
const interval = intervals[i]
if (interval[0] >= right) {
ans++
right = interval[1]
}
}
return intervals.length - ans
};
空间:O(logn) 排序所使用的栈空间 时间:O(nlogn) 排序的时间复杂度
排序后双指针比较
class Solution:
def eraseOverlapIntervals(self, intervals):
ln = len(intervals)
if ln < 2:
return 0
intervals = sorted(intervals, key=lambda x: (x[1], x[0]))
ret = 0
left = 0
for right in range(1, ln):
if intervals[right][0] < intervals[left][1]:
ret += 1
else:
left = right
return ret
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.size() == 0) {
return 0;
}
//按结束时间从小到大排序
sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
return a[1] < b[1];
});
int end = intervals[0][1];
int res = 1;
for (int i = 1; i < intervals.size(); ++i) {
if (intervals[i][0] >= end) {
++res;
end = intervals[i][1];
}
}
return intervals.size() - res;
}
思路
dp
代码
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
int n = intervals.length;
int[] f = new int[n];
Arrays.fill(f, 1);
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (intervals[j][1] <= intervals[i][0]) {
f[i] = Math.max(f[i], f[j] + 1);
}
}
}
return n - Arrays.stream(f).max().getAsInt();
}
}
复杂度
时间复杂度:O(nlogn)
空间复杂度:O(1)
class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> a[1] - b[1]); int end = intervals[0][1], count = 1; for (int i = 1; i < intervals.length; i++) { if (intervals[i][0] >= end) { count++; end = intervals[i][1]; } } return intervals.length - count; } }
贪心算法,先对数组进行排序,注意应该用结束时间来排,因为如果按开始时间,可能整个区间会非常大没有办法得到正确答案。但用结束时间进行排序的话,如果pre_end比curr_start要大,证明现在的这个区间会重复不能要,直接不做任何处理到下一个,反之区间就增长并且把pre_end更新成为curr_end的值,最后返回n-不重复的区间长度。
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), [](const auto& a, const auto& b) {
return a[1] < b[1];
});
int r = intervals[0][1];
int noOverlap = 1;
for (int i = 1; i < intervals.size(); ++i) {
if (intervals[i][0] >= r) {
noOverlap++;
r = intervals[i][1];
}
}
return intervals.size() - noOverlap;
}
};
贪心
代码
package main
import ( "fmt" "sort" )
func eraseOverlapIntervals(intervals [][]int) int { var flag int sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] }) fmt.Println(intervals) for i:=1;i<len(intervals);i++{ if intervals[i-1][1]>intervals[i][0]{ flag++ intervals[i][1] = min(intervals[i-1][1],intervals[i][1]) } } return flag } func min(a,b int)int{ if a > b{ return b } return a }
## 复杂度
+ > 时间:O(nlogn)
+ > 空间:O(1)
c Code:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) {
return 0;
}
sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b) {
if (a[1] != b[1]) {
return (a[1] < b[1]);
} else {
return (a[0] < b[0]);
}
});
int res = 0;
vector<int> pre = intervals[0];
for (int i = 1; i < intervals.size(); ++i) {
if (pre[1] > intervals[i][0]) {
++res;
} else {
pre = intervals[i];
}
}
return res;
}
};
复杂度分析
令 n 为数组长度。
var eraseOverlapIntervals = function(intervals) {
intervals.sort((a, b) => {
return a[1] - b[1]
})
let count = 1
let end = intervals[0][1]
for(let i = 1; i < intervals.length; i++) {
let interval = intervals[i]
if(interval[0] >= end) {
end = interval[1]
count += 1
}
}
return intervals.length - count
};
class Solution {
public:
// 按照区间右边界排序
static bool cmp (const vector<int>& a, const vector<int>& b) {
return a[1] < b[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.size() == 0) return 0;
sort(intervals.begin(), intervals.end(), cmp);
int count = 1; // 记录非交叉区间的个数
int end = intervals[0][1]; // 记录区间分割点
for (int i = 1; i < intervals.size(); i++) {
if (end <= intervals[i][0]) {
end = intervals[i][1];
count++;
}
}
return intervals.size() - count;
}
};
class 无重叠区间_435 {
public int eraseOverlapIntervals(int[][] intervals) {
// 想找最少删除的 转化为能放下最多的LIS
// 按照右边界排序 始终找左边界比右边界大的下一个 能让右边界最小
Arrays.sort(intervals, Comparator.comparingInt(a -> a[1]));
int end = intervals[0][1];
int count = 1;
for(int i = 1; i < intervals.length; i++) {
if(end <= intervals[i][0]) {
end = intervals[i][1];
count ++;
}
}
return intervals.length - count;
}
}
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x: x[1])
n = len(intervals)
right = intervals[0][1]
ans = 1
for i in range(1, n):
if intervals[i][0] >= right:
ans += 1
right = intervals[i][1]
return n - ans
https://leetcode-cn.com/problems/non-overlapping-intervals/
Greedy
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
# print(intervals)
count = 0
i = 0
while(i < len(intervals)):
count += 1
j = i + 1
while (j < len(intervals) and intervals[j][0] < intervals[i][1]):
j += 1
i = j
return len(intervals) - count
# Greedy
# 1.Sweeping line / diff
# 2.Sort
# sort by starting point => the minimum number of intervals to cover the whole
# sort by ending point => the maximum number of intervals that are non-overlapping
# Dp
#
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals == null || intervals.length <= 1) return 0;
Arrays.sort(intervals, (a, b) -> a[1] - b[1]);
int count = 1;
int[] interval = intervals[0];
for (int i = 1; i < intervals.length; i++){
if (intervals[i][0] >= interval[1]){
count++;
interval = intervals[i];
}
}
return intervals.length - count;
}
}
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x : x[1])
n = len(intervals)
ans = 1
right = intervals[0][1]
for i in range(1, n):
if right <= intervals[i][0]:
ans += 1
right = intervals[i][1]
return n - ans
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[1] - interval2[1];
}
});
int n = intervals.length;
int right = intervals[0][1];
int ans = 1;
for (int i = 1; i < n; ++i) {
if (intervals[i][0] >= right) {
++ans;
right = intervals[i][1];
}
}
return n - ans;
}
}
贪心
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) {
return 0;
}
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
return u[1] < v[1];
});
int n = intervals.size();
int right = intervals[0][1];
int ans = 1;
for (int i = 1; i < n; ++i) {
if (intervals[i][0] >= right) {
++ans;
right = intervals[i][1];
}
}
return n - ans;
}
};
时间复杂度:O(nlogn)
空间复杂度:O(logn)
贪心法
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x: x[1])
n = len(intervals)
right = intervals[0][1]
ans = 1
for i in range(1, n):
if intervals[i][0] >= right:
ans += 1
right = intervals[i][1]
return n - ans
Python3 Code:
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return
n = len(intervals)
intervals.sort(key=lambda x:x[1])
right = intervals[0][1]
ans =1
for i in range(1,n):
if intervals[i][0] >=right:
ans+=1
right = intervals[i][1]
return n-ans
复杂度分析
令 n 为数组长度。
思路:主要使用贪心,对原始数据进行重新排序(这是是对区间的结束进行排序的),第一执行完就记录其结束的时间,然后取下一个区间的开始时间与之比较,如果开始时间大于上一个的结束时间,则计数+1,反之则更新结束时间。
class Solution { public int eraseOverlapIntervals(int[][] intervals) { PriorityQueue<int[]> queue =new PriorityQueue<>(new Comparator<int[]>() { @Override public int compare(int[] o1, int[] o2) { return o1[1]-o2[1]; } }); for(int i[]:intervals){ queue.add(i); } int res =0; int end =0; end=queue.peek()[0]; while (!queue.isEmpty()){ int temo[] = queue.poll(); if(temo[0]>=end){ end=temo[1]; }else{ res++; } } return res; } }
var eraseOverlapIntervals = function(intervals) { if (!intervals.length) { return 0; }
intervals.sort((a, b) => a[1] - b[1]);
const n = intervals.length;
let right = intervals[0][1];
let ans = 1;
for (let i = 1; i < n; ++i) {
if (intervals[i][0] >= right) {
++ans;
right = intervals[i][1];
}
}
return n - ans;
};
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
auto cmp = [](vector<int>& v1, vector<int>& v2)
{
return v1[1] < v2[1];
};
if(intervals.empty()) return 0;
sort(intervals.begin(), intervals.end(), cmp);
int N = intervals.size();
int maxRemain = 1;
int curRight = intervals[0][1];
for(int i=1; i<N; i++)
{
if(intervals[i][0] >= curRight)
{
maxRemain++;
curRight = intervals[i][1];
}
}
return N-maxRemain;
}
};
Space:O(n) TIme:O(nlogn)
https://leetcode-cn.com/problems/non-overlapping-intervals/
剩下的相邻区间前面区间的结束和后面区间的开始是一个非严格递增序列
class Solution:
def lengthLIS(self,A:List[int])-> int:
d = []
for s,e in A:
i = bisect.bisect_left(d,e)
if i < len(d):
d[i] = e
elif not d or d[-1]<=s:
d.append(e)
return len(d)
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
n = len(intervals)
if n==0:return 0
ans = 1
intervals.sort(key = lambda a:a[0])#对开始序列排序
return n-self.lengthLIS(intervals)
直接贪心:贪心的选择下一个区间起点大于上一个终点的区间,没有就跳过
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort(key=lambda x: x[1])
n = len(intervals)
right = intervals[0][1]
ans = 1
for i in range(1, n):
if intervals[i][0] >= right:
ans += 1
right = intervals[i][1]
return n - ans
时间复杂度分析:
class Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int: if not intervals: return 0
intervals.sort()
n = len(intervals)
f = [1]
for i in range(1, n):
f.append(max((f[j] for j in range(i) if intervals[j][1] <= intervals[i][0]), default=0) + 1)
return n - max(f)
class Solution:
def lengthOfLIS(self, A: List[int]) -> int:
d = []
for s, e in A:
i = bisect.bisect_left(d, e)
if i < len(d):
d[i] = e
elif not d or d[-1] <= s:
d.append(e)
return len(d)
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
n = len(intervals)
if n == 0: return 0
ans = 1
intervals.sort(key=lambda a: a[0])
return n - self.lengthOfLIS(intervals)
时间复杂度:O(nlogn) 空间复杂度:O(n)
C++ Code:
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b)
{
if(a[0]==b[0])
return a[1]<b[1];
return a[0]<b[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if(intervals.size()==0)
return 0;
sort(intervals.begin(),intervals.end(),cmp);
int right = intervals[0][1];
int res = 0;
for(int i=1;i<intervals.size();++i)
{
if(right<=intervals[i][0])
right = intervals[i][1];
else if(right>intervals[i][0]&&right<=intervals[i][1])
++res;
else if(right>intervals[i][1])
{
++res;
right = intervals[i][1];
}
}
return res;
}
};
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b)
{
if(a[0]==b[0])
return a[1]<b[1];
return a[0]<b[0];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if(intervals.size()==0)
return 0;
sort(intervals.begin(),intervals.end(),cmp);
int right = intervals[0][1];
int res = 0;
for(int i=1;i<intervals.size();++i)
{
if(right<=intervals[i][0])
right = intervals[i][1];
else if(right>intervals[i][0]&&right<=intervals[i][1])
++res;
else if(right>intervals[i][1])
{
++res;
right = intervals[i][1];
}
}
return res;
}
};
javascript
/*
* @lc app=leetcode.cn id=435 lang=javascript
*
* [435] 无重叠区间
*/
// @lc code=start
/**
* @param {number[][]} intervals
* @return {number}
*/
var eraseOverlapIntervals = function(intervals) {
if (!intervals.length) {
return 0
}
// 由于区间的起点总是小于终点
// 根据区间的终点排序
// 按照右边界排序,从左到右遍历,这样选择的空间最小,留给下个空间最大,
// 从而移除的更少
intervals.sort((a, b) => a[1] - b[1])
const n = intervals.length
// 先取第一个区间
let right = intervals[0][1]
let ans = 1
// 从第二个区间开始比较
for (let i = 1; i < n; i++) {
const left = intervals[i][0]
// 若当前的起点比上一个区间的终点都大,则说明两个区间不重叠了
if (left >= right) {
++ans
right = intervals[i][1]
}
}
// 最终总的减去符合题意的,则为需要移除的
return n - ans
};
// @lc code=end
贪心
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> {return a[1] - b[1];});
int end = intervals[0][1];
int count = 1;
for (int i = 1; i < intervals.length; ++i) {
if (intervals[i][0] >= end) {
end = intervals[i][1];
++count;
}
}
return intervals.length - count;
}
}
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[1] == b[1] ? b[0] - a[0] : a[1] - b[1]);
int end = Integer.MIN_VALUE, count = 0;
for (int[] cur : intervals) {
if (cur[0] >= end) {
count++;
end = cur[1];
}
}
return intervals.length - count;
}
时间复杂度:O(NlogN) 空间复杂度:O(1)
class Solution:
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
intervals.sort(key=lambda x: x[1])
end, res = float('-inf'), 0
for t in intervals:
if t[0] < end:
# remove the interval
res += 1
else:
end = t[1]
return res
Time complexity: O(NlogN)
Space complexity: O(1)
1 <= intervals.length <= 2 * 10^4
intervals[i].length == 2
-2 * 10^4 <= starti < endi <= 2 * 10^4
intervals = [[1,2],[2,3],[3,4],[1,3]]
intervals = [[1,2],[1,3],[2,3],[3,4]]
|. |
|. |
cur.end > next.start
|. |
|. |
keep the interval whose end is smaller
|. |
|. |
|. |
|. |
- edge case: one interval
- sort by start
- one for loop, compare cur with the next, keep a counter
for (int next = 1; next < intervals.length; next++) {
if (intervals[cur][1] > intervals[next][0]) {
// keep whose end is smaller
count++;
if (intervals[cur][1] >= intervals[next][1]) {
// keep next, remove cur
cur = next;
}
}
else {
cur = next;
}
}
note to change the syntax
Input: intervals = [[1,2],[2,3],[3,4],[1,3]]
Output: 1
intervals = [[1,2],[1,3],[2,3],[3,4]]
Input: intervals = [[1,2],[1,2],[1,2]]
Output: 2
intervals = [[1,2],[1,2],[1,2]]
***Input:
[[0,2],[1,3],[2,4],[3,5],[4,6]]
cur. n count = 1
cur. n
cur. n
n = intervals.length
Time: O(nlogn) + O(n) = O(nlogn)
Space: O(1)
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 1) return 0;
Arrays.sort(intervals, (a, b) -> (a[0] - b[0]));
int cur = 0;
int count = 0;
for (int next = 1; next < intervals.length; next++) {
if (intervals[cur][1] > intervals[next][0]) {
// keep whose end is smaller
count++;
if (intervals[cur][1] >= intervals[next][1]) {
// keep next, remove cur
cur = next;
}
}
else {
cur = next; // note this line
}
}
return count;
}
}
435. 无重叠区间
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/non-overlapping-intervals/
前置知识
暂无
题目描述