class Solution {
public:
int eraseOverlapIntervals(vector<vector<int> >& intervals) {
int i,res=0;
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
if(u[0]<v[0])
return 1;
else if(u[0]==v[0])
{if(u[1]<=v[1])
return 1;
else
return 0;}
else
return 0;
});
for(i=0;i<intervals.size();)
{
int t_end=intervals[i++][1];
while(i<intervals.size()&&intervals[i][0]<t_end)
{++res;++i;}
}
return res;
}
};
仔细对照看了几遍终于知道自己错哪了。我没有更新t_end,虽然可能重叠,但当前的end并不是最小end。因此为了得到最小移除区间数,需要时刻更新end。
但还是有两个问题,第一,咱还是我写不出来这个排序的lambda表达式,再有为什么只需要u[0]<v[0]就够了?感觉可以自我回答下,因为下文有更新end,所以这个即使不排序也可以。
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int> >& intervals) {
int i,res=0;
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
return u[0]<v[0];
// if(u[0]<v[0])
// return 1;
// else if(u[0]==v[0])
// {if(u[1]<=v[1])
// return 1;
// else
// return 0;}
// else
// return 0;
});
if(intervals.empty())
return res;
int t_end=intervals[0][1];
for(i=1;i<intervals.size();++i)
{
if(intervals[i][0]<t_end)
{t_end=min(t_end,intervals[i][1]);
res++;}
else
t_end=intervals[i][1];
}
return res;
}
};
但更为巧妙的贪心算法是用结束时间排序,这样,每一步都能保证获得的结果在当前情况下最优。使用开始时间排序的话,不知道从开始到结束跨越的时间。
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int> >& intervals) {
if(intervals.empty())
return 0;
int count=1;
sort(intervals.begin(), intervals.end(), [](const auto& u, const auto& v) {
return u[1]<v[1];
});
int t_end=intervals[0][1];
for(int i=0;i<intervals.size();i++)
if(t_end<=intervals[i][0])
{
t_end=intervals[i][1];count++;
}
return intervals.size()-count;
}
};
其实这样看来,反而是动态规划有点难做了,首先是初始状态,应该是dp[1~n]=1,因为每个vector自己都可以看成一个不重叠的解。
然后是转移方程,dp[i]=max(dp[i],dp[j]+1), if interals[i][0]>=intervals[j][1]。
不是很好讲清楚,我自己也说不清楚,又是模模糊糊的能够认同。