【Leetcode】Merge Intervals

本文介绍了一种有效的算法,用于合并一系列可能重叠的时间区间。通过排序和迭代处理,该算法能够快速找出并合并所有重叠的部分,适用于多种场景如日程安排、资源分配等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].

分析:

先把start和end全提出来,分别保存在两个数组中,并对这两个数组进行排序,排序能重新整合各个区间,并且保证了上一个区间的end小于下个区间的end,这是非常重要的一点,将简化了后续的判断。用一个List泛型集合来保存最后筛选结果。首先对start进行遍历,即对所有区间进行遍历,判断下个区间的start是否大于当前区间的end,若大于则证明没有包含关系,否则证明有包含关系,然后对下两个区间进行同样的判断,为了保证合并后区间的start不变,特用到变量j来保证区间start的正确性,只有当不存在包含关系,才执行j++操作。另外同时要注意到i是否为最后一项,若为最后一项直接跳出判断,保存区间。


Java版本:

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
class Solution {
    public List<Interval> merge(List<Interval> intervals) {
        //先分离start 和 end
        int n = intervals.size();
        int[] starts = new int[n];
        int[] ends = new int[n];
        for(int i = 0; i < n; i++){
            starts[i] = intervals.get(i).start;
            ends[i] = intervals.get(i).end;
        }
        Arrays.sort(ends);
        Arrays.sort(starts);
        List<Interval> res = new ArrayList<Interval>();
        //对start进行遍历,j用来固定区间的start,
        //然后判断下一个区间的start是否大于前一个区间的end,同时对i是否为最后项进行判断
        //大于的话,说明没包含关系,则直接返回start[j],end[i]
        //否则证明有包含关系,i++,下两个区间进行比较
        //简单理解就是i保存最终结果的end,j用来保存最终结果的start
        for(int i = 0, j = 0; i < n; i++){
            if(i == n - 1 || starts[i + 1] > ends[i]){
                res.add(new Interval(starts[j], ends[i]));
                j = i + 1;
            }
        }
        return res;
    }
}

Python版本:

# Definition for an interval.
# class Interval:
#     def __init__(self, s=0, e=0):
#         self.start = s
#         self.end = e

# class Solution:
#     def merge(self, intervals):
#         """
#         :type intervals: List[Interval]
#         :rtype: List[Interval]
#         """
#         out = []
#         for i in sorted(intervals, key=lambda i: i.start):
#             if out and i.start <= out[-1].end:
#                 out[-1].end = max(out[-1].end, i.end)
#             else:
#                 out += i,
#         return out
class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[Interval]
        :rtype: List[Interval]
        """
        if len(intervals) == 0: return []
        intervals = sorted(intervals, key = lambda x: x.start)
        res = [intervals[0]]
        for n in intervals[1:]:
            if n.start <= res[-1].end: res[-1].end = max(n.end, res[-1].end)
            else: res.append(n)
        return res

此处用到了lambda表达式,先将intervals里面所有区间的start进行排序,已保证所有区间内的start是从小到大排序的(注意Java版本是将start和end都进行了排序,所以后面合并区间时就不用对end取最大值操作),并当,前一个区间end大于下个区间的start时,证明有合并区间,取两合并区间end的最大值,作为新区间的end,接着下个interval进行判断。


C++版本:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    vector<Interval> merge(vector<Interval>& ins) {
        if (ins.empty()) return vector<Interval>{};
        vector<Interval> res;
        sort(ins.begin(), ins.end(), [](Interval a, Interval b){return a.start < b.start;});
        res.push_back(ins[0]);
        for (int i = 1; i < ins.size(); i++) {
            if (res.back().end < ins[i].start) res.push_back(ins[i]);
            else
                res.back().end = max(res.back().end, ins[i].end);
        }
        return res;
        }
};

思路同Python版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值