Leetcode P0056"Merge Intervals" 题解

2020/08/25 Leetcode

博文中会简要介绍Leetcode P0056题目分析及解题思路。

“Merge Intervals”是一道比较典型的利用排序简化算法复杂度的题目,也蕴含了一定的贪心的思想,但主要还是基本的边界条件判断。

Given a collection of intervals, merge all overlapping intervals.

Example 1:

Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]

Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].

首先按照开始时间排序。这样一来我们从前往后遍历,后面的interval的开始时间一定大于等于前面的,从而不用考虑后面开始时间更早的情况。

    考虑以下两个边界条件:

    merged[1] >= interval[0],即当前interval的开始时间在当前merged过后的interval的结束时间之前或恰好就是结束时间,此时需要merge,根据结束时间来更新当前merged过后的interval

    merged[1] < interval[0],即当前interval与当前merged过后的interval不重叠,存储merged过后的interval,重新开始新一轮merge

以下是Java的题解代码实现。

class Solution {
    public int[][] merge(int[][] intervals) {
        if (intervals == null || intervals.length <= 1)
            return intervals;
        
        Arrays.sort(intervals, (int[] i1, int[] i2) -> i1[0]-i2[0]);
        
        List<int[]> mergedIntervals = new ArrayList<>();
        int[] merged = intervals[0];
        for (int[] interval: intervals) {
            if (interval[0] <= merged[1]) {
                merged[1] = Math.max(merged[1], interval[1]);
            }
            else {
                mergedIntervals.add(merged);
                merged = interval;
            }
        }
        
        mergedIntervals.add(merged);
        // Java 8 stream()方法
        // return mergedIntervals.stream().toArray(int[][]::new);
        return mergedIntervals.toArray(new int[0][0]);
    }
}

以下是C++的题解代码实现。

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if (intervals.size() == 0)
            return intervals;
        
        // 这里的Lambda表达式形参需要是引用类型,否则会有大量时间损耗在拷贝上
        sort(intervals.begin(), intervals.end(), 
             [](const vector<int> &v1, const vector<int> &v2) -> bool {
                 return v1[0] < v2[0];
             });
        
        vector<vector<int>> merged_intervals;
        vector<int> merged = intervals[0];
        for (vector<int> interval: intervals) {
            if (merged[1] >= interval[0])
                merged[1] = max(merged[1], interval[1]);
            else {
                merged_intervals.push_back(merged);
                merged = interval;
            }
        }
        
        merged_intervals.push_back(merged);
        return merged_intervals;
    }
};

Search

    Table of Contents