力扣区间题:合并区间、插入区间

我们可以将区间按照左端点升序排列,然后遍历区间进行合并操作。

我们先将第一个区间加入答案,然后依次考虑之后的每个区间:

  • 如果答案数组中最后一个区间的右端点小于当前考虑区间的左端点,说明两个区间不会重合,因此我们可以直接将当前区间加入答案数组末尾;
  • 否则,说明两个区间重合,我们需要用当前区间的右端点更新答案数组中最后一个区间的右端点,将其置为二者的较大值。
class Solution {
    public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
        List<int[]> ans = new ArrayList<>();
        ans.add(intervals[0]);
        for (int i = 1; i < intervals.length; ++i) {
            int s = intervals[i][0], e = intervals[i][1];
            if (ans.get(ans.size() - 1)[1] < s) {
                ans.add(intervals[i]);
            } else {
                ans.get(ans.size() - 1)[1] = Math.max(ans.get(ans.size() - 1)[1], e);
            }
        }
        return ans.toArray(new int[ans.size()][]);
    }
}

 

这个有两种解法,一种就是直接将这个要插入的区间加入数组,让合并区间的算法走一遍,就可以了。

第二种算法:

我们可以遍历区间列表 intervalsintervalsintervals,记当前区间为 a,对于每个区间有三种情况:

  • 当前区间在新区间的右侧,即 newInterval[1]<a[0] 此时如果新区间还没有被加入,那么将新区间加入到答案中,然后将当前区间加入到答案中。
  • 当前区间在新区间的左侧,即 a[1]<newInterval[0],此时将当前区间加入到答案中。
  • 否则,说明当前区间与新区间有交集,我们取当前区间的左端点和新区间的左端点的最小值,以及当前区间的右端点和新区间的右端点的最大值,作为新区间的左右端点,然后继续遍历区间列表。

遍历结束,如果新区间还没有被加入,那么将新区间加入到答案中。

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        ArrayList<int[]> ints = new ArrayList<>();
        //记录要合并数组的头区间
        int start  = newInterval[0];
        //记录要合并数组的尾区间
        int end = newInterval[1];
        //要插入区间是否已经插入
        boolean b = false;
        for(int[] a :intervals) {
            //要插入的区间右端点小于当前区间的左端点
             if (end<a[0]){
            //如果要插入的区间还没有插入的话,就说明此时要插入的区间可以插入了,不和后面区间合并了。
                if (!b){
                    ints.add(new int[]{start,end});
                     b = true;
                }
               //将不需要合并区间插入
                ints.add(a);
             //要插入区间左端点大于此时区间的右端点,说明不重合,可以插入了
            }else if (a[1]<start){
                ints.add(a);
            }
            else {
            //此时肯定是重合了,则左端点选出最小的,右端点选出最大的。
                start = Math.min(start,a[0]);
                end = Math.max(end,a[1]);
            }
        }
        //如果遍历完了,还没有插入的话,直接再最后插入。
        if (!b){
            ints.add(new int[]{start,end});
        }
        return ints.toArray(new int[ints.size()][]);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日上三杆快起床

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值