LeetCode第57题插入区间

继续打卡算法题,今天学习的是LeetCode第57题插入区间,这道题目是道中等题。算法题的一些解题思路和技巧真的非常巧妙,每天看一看算法题和解题思路,我相信对我们的编码思维和编码能力有一些提升。

分析一波题目

上一题56题合并区间 已经学习了怎么判断重叠区间,怎么合并区间,本题就不难了。最简单的做法,我们可以把要插入的区间和原区间集合先添加到一个新的区间集合,然后排序,最后做一次合并,后面的流程和56题一样。

java 复制代码
        int[][] newIntervals = new int[intervals.length+1][1];
        System.arraycopy(intervals, 0, newIntervals, 0, intervals.length);
        newIntervals[newIntervals.length-1] = newInterval;
        Arrays.sort(newIntervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));

通过上面的代码组成了新的区间集合,只要对newIntervals中重叠的区间进行合并,这个做法虽好理解,但是性能就降低了,因为题目已经说明原区间已经按左边界排序了,因此本题可以有更优的做法。

由于原区间集已经有序了,我们可以按如下步骤来执行插入操作。

1、将与要插入的区间无重叠的,加入到新的区间集

2、将与要插入的区间有重叠的,执行合并

3、将与要插入的区间无重叠的,加入到新的区间集

本题解题技巧

1、将原区间集分段,分为与新区间左边界偏离的一段,与新区间有重叠的,与新区间右边界偏离的一段

编码解决

重组区间集合,再排序解法

java 复制代码
class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {

        //存储结果
        LinkedList<int[]> result = new LinkedList<>();
        //按左边界排序
        int[][] newIntervals = new int[intervals.length+1][1];
        //重组新区间集
        System.arraycopy(intervals, 0, newIntervals, 0, intervals.length);
        newIntervals[newIntervals.length-1] = newInterval;
        Arrays.sort(newIntervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
        System.out.println(newIntervals.length);
        //第一个先加入结果
        result.add(newIntervals[0]);
        //从第二个开始判断是否重叠
        for (int i = 1; i < newIntervals.length; i++) {
            //和前面的重叠了
             System.out.println(i);
            System.out.println(newIntervals[i]);
            if (newIntervals[i][0] <= result.getLast()[1]) {
                int start = result.getLast()[0];
                int end = Math.max(newIntervals[i][1], result.getLast()[1]);
                //合并之前,最后一个需要删除
                result.removeLast();
                //合并成新区间,并加入结果
                result.add(new int[]{start, end});
            }
            else {
                //没有重叠,加入结果
                result.add(newIntervals[i]);
            }   
        }
        return result.toArray(new int[result.size()][]);
    }
}

不重组区间集且不重新排序解法

java 复制代码
class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        //存储结果
        int[][] result = new int[intervals.length + 1][2];
        int idx = 0;
        
        // 1、首先将新区间左边且相离的区间加入结果集
        int i = 0;
        while (i < intervals.length && intervals[i][1] < newInterval[0]) {
            result[idx++] = intervals[i++];
        }
        // 2、接着判断当前区间是否与新区间重叠,重叠的话就进行合并
        while (i < intervals.length && intervals[i][0] <= newInterval[1]) {
            newInterval[0] = Math.min(intervals[i][0], newInterval[0]);
            newInterval[1] = Math.max(intervals[i][1], newInterval[1]);
            i++;
        }
        //合并的结果存入
        result[idx++] = newInterval;

        // 3、最后将新区间右边且相离的区间加入结果集
        while (i < intervals.length) {
            result[idx++] = intervals[i++];
        }

        return Arrays.copyOf(result, idx);
    }
}

总结

1、通过借助56题合并区间思路,可以解决本题,合并区间和判断区间重叠的方法同样适用

2、借助原区间集本身有序的特性,通过拆分3步,根据新区间和原区间集的关系,要么有交集,要么在区间集左边,执行插入操作,并且时间复杂度控制在O(n)。

相关推荐
St_Ludwig36 分钟前
C语言 蓝桥杯某例题解决方案(查找完数)
c语言·c++·后端·算法·游戏·蓝桥杯
vener_1 小时前
LuckySheet协同编辑后端示例(Django+Channel,Websocket通信)
javascript·后端·python·websocket·django·luckysheet
计算机毕设孵化场1 小时前
计算机毕设-基于springboot的多彩吉安红色旅游网站的设计与实现(附源码+lw+ppt+开题报告)
vue.js·spring boot·后端·计算机外设·课程设计·计算机毕设论文·多彩吉安红色旅游网站
爪哇学长1 小时前
解锁API的无限潜力:RESTful、SOAP、GraphQL和Webhooks的应用前景
java·开发语言·后端·restful·graphql
战神刘玉栋2 小时前
《SpringBoot、Vue 组装exe与套壳保姆级教学》
vue.js·spring boot·后端
码到成功>_<3 小时前
Spring Boot实现License生成和校验
数据库·spring boot·后端
Ztiddler4 小时前
【npm设置代理-解决npm网络连接error network失败问题】
前端·后端·npm·node.js·vue
货拉拉技术4 小时前
多元消息融合分发平台
javascript·后端·架构
醒过来摸鱼4 小时前
【Golang】协程
开发语言·后端·golang
谷大羽4 小时前
Kafka Stream实战教程
spring boot·后端·中间件·kafka·stream