56. Merge Intervals的C++解法(重写sort函数)

题目描述:https://leetcode.com/problems/merge-intervals/

挑战中要求使用O(nlogn)的时间复杂度和O(1)的额外空间复杂度,所以使用了sort先对区间进行排序,然后在原容器上进行融合和删除操作,注意有删除操作之后i不需要自增了,后一个会自动移上来,如果无脑自增会跳过很多值。
但是这个方法比较慢。

class Solution {
public:
    static bool cmp(const Interval &a, const Interval &b){
        return (a.start<b.start);
    }
    vector<Interval> merge(vector<Interval> &intervals) {
        if (intervals.size()==0) return intervals;
        sort(intervals.begin(),intervals.end(),cmp);
        int head=intervals[0].start;
        int tail=intervals[0].end;
        int index=0;
        int i=1;
        while (i<intervals.size())
        {
            
            if (intervals[i].start<=tail)
                if (intervals[i].end<=tail) intervals.erase(intervals.begin()+i);
                else 
                {
                    tail=intervals[i].end;
                    intervals[index].end=tail;
                    intervals.erase(intervals.begin()+i);
                }
            else
            {
                index=i;
                head=intervals[i].start;
                tail=intervals[i].end;
                i++;
            }
            
        }
        return intervals;
    }
};

如果没有这个限制,可以考虑用类似hash表的方法做,本来我是用了vector,之后看到一个很棒的方法用了map,好处在于:
1.由于不知道数字的范围,不需要开很大的数组
2.vector处理不了[0,0]这样的情况,会判别为不存在,但是map即使是map[0],也会被计算在内。

class Solution {
public:
	vector<Interval> merge(vector<Interval>& intervals) {
		map<int, int> terminals; 
		for (auto& i : intervals){
			terminals[i.start] += 1; 
			terminals[i.end] -= 1; 
		}
		vector<Interval> res; 
		int levels = 0, start; 
		for (auto& p : terminals){
            //map是默认以key值排序的
			int num = p.first, cnt = p.second; 
			if (levels == 0)//第一次碰上0是一个区间的开始
				start = num; 
			levels += cnt; 
			if (levels == 0){//再一次碰上0是区间的结束
				res.push_back(Interval(start, num)); 
			}
		}
		return res; 
	}
}; 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值