Leetcode第435. 无重叠区间 C++解法

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]。
不是很好讲清楚,我自己也说不清楚,又是模模糊糊的能够认同。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值