合并区间之问题拆解

前言

区间合并需要定位一端的顺序,这样合并起来就非常轻松。

一、合并区间

在这里插入图片描述

二、题解

package com.xhu.offer.top100;

import java.util.*;

//合并区间
public class Merge {
    /*
    target:合并两个重合的区间。
    如何定义重合区间?
    1-完成重合,直接保留外层区间即可。
    2-部分重合,保留左区间的左,右区间的右。
    对于完全重合区间,如果是右区间完成重合左区间,那么还得不断合并左边的区间,知道不重合为止。
     */
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, Comparator.comparingInt(o -> o[0]));

        List<int[]> rs = new ArrayList<>();
        rs.add(intervals[0]);

        int len = intervals.length;
        for (int i = 1; i < len; i++) {
            int[] left = rs.get(rs.size() - 1);
            int[] right = intervals[i];
            //判断重合情况
            //1-不重合
            if (left[1] < right[0]) {
                rs.add(right);

                continue;
            }
            int leftBound = left[0];//先拿到左边界,看是否合并之后有延申。
            //重合情况
            left[0] = left[0] < right[0] ? left[0] : right[0];
            left[1] = left[1] < right[1] ? right[1] : left[1];
            //如果左边界越界,则合并左边的相邻区间
            if (left[0] < leftBound) {
                int j = rs.size() - 2;
                while (j >= 0) {
                    int[] cur = rs.get(j);
                    //不重合
                    if (cur[1] < left[0]) continue;

                    --j;//不管如何,这个节点该被删除。

                    //部分重合 || 完全重合但未延申
                    if (cur[1] >= left[0] && cur[0] <= left[0]) {
                        left[0] = cur[0];
                        break;
                    }
                    //删节点
                    int cnt = rs.size() - 2 - j;
                    while (cnt-- > 0) rs.remove(j + 1);
                }
            }
        }
        int[][] res = new int[rs.size()][2];
        return rs.toArray(res);
    }


}


class Merge2 {
    //排完序,就利用好有序就很简单了。
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, Comparator.comparingInt(o -> o[0]));

        List<int[]> rs = new ArrayList<>(Collections.singleton(intervals[0]));

        for (int i = 1; i < intervals.length; i++) {
            int[] left = rs.get(rs.size() - 1);
            int[] right = intervals[i];
            //判断重合情况,left[0]永远是最小的.
            //不重合
            if (left[1] < right[0]) {
                rs.add(right);

                continue;
            }
            //重合的情况,直接合并
            if (left[1] < right[1]) left[1] = right[1];
        }

        return rs.toArray(new int[0][]);
    }
}

总结

1)区间合并
2)问题拆解

参考文献

[1] LeetCode 合并区间

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值