Leecode热题100-56.合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

很简单的题目,关键看怎么想,直接上代码了,不懂私信或者留言

class Solution {
    /**本题的思路是:先把原来的数组按照第一维从小到大排序,如果第一维相同按照第二位从大到小排序(第二维无所谓,从小到大也许)
    这样就能保证类似(1,2),(1,6)这样的区间排完序之后是(1,6)(1,2),这样遍历完第一个区间之后获得的end是6,第二个区间被第一个区间包围可以忽略
    然后如果下个区间是(7,10)就把第一个进行结算,如果下个是(3,8)就把end扩展到8并试图继续扩展*/
    public int[][] merge(int[][] intervals) {
        /**如果只有一个区间就没啥好合并的了,直接返回即可 */
        if(intervals.length == 1) {
            return intervals;
        }
        /**大于1个区间先排序,排序规则:按照第一维(区间开始)从小到大进行排序,如果第一维相同按照第二位从大到小排序 */
        Arrays.sort(intervals, (a,b)->a[0] != b[0]? a[0] - b[0] : b[1] - a[1]);
        /**把第一个区间的开头和结尾定义为start和end,每遍历完一个区间再给这两个赋值*/
        int start = intervals[0][0];
        int end = intervals[0][1];
        /**为减少空间浪费,我这里复用intervals作为结果数组,但是大概率是装不满的,所以需要定义一个validLen表示结果的有效长度,目前还没有*/
        int validLen = 0;
        for(int i = 1; i < intervals.length; i++) {
            /**如果这个区间被之前的区间覆盖了,就跳过 */
            if(intervals[i][0] >= start && intervals[i][1] <= end) {
                continue;
            }
            /**intervals[i][0]肯定是大于start的,如果intervals[i][1]小于等于end,那前面的if就返回了,所以这里intervals[i][1]肯定比end大,可以扩展end*/
            if(intervals[i][0] <= end) {
                end = intervals[i][1];
            } else {
                /**如果不重合就结算前一个区间并开始下个区间 */
                intervals[validLen][0] = start;
                intervals[validLen ++][1] = end; 
                /**开始下个区间,重新计算start和end */
                start = intervals[i][0];
                end = intervals[i][1];
            }
        }
        /**对于最后一个区间,假设它和上个区间重合则它只是扩展了上个区间,还没结算
        如果它和上个区间不重合,则开始了一个新的区间,也没有结算
        这两种情况都需要把最后一个区间结算一下 */
        intervals[validLen][0] = start;
        intervals[validLen++][1] = end;
        /**拷贝有效的长度返回 */
        return Arrays.copyOf(intervals, validLen);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值