我是靠谱客的博主 含糊月光,最近开发中收集的这篇文章主要介绍leetcode_57.插入区间,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

给出一个无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例 1:

输入: intervals = [[1,3],[6,9]], newInterval = [2,5]
输出: [[1,5],[6,9]]

示例 2:

输入: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出: [[1,2],[3,10],[12,16]]
解释: 这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。

解析:本题是基于上一题的修改版,因此提供两种解决方法,第一种是在上一题的基础上修改,第二种是不基于上一题的新思路。

第一种,在上一题的基础上修改。上一题提供的起始集合便是未排序,包含重叠区间的给定容器。而本题是要求将给定区间插入原集合中。最简单的办法便是将区间直接加入原集合,然后交付由上一题的函数计算便可。
如何减少时间,上一题的许多时间消耗在了给集合排序上,我们可以利用原集合有序的特点,使用二分法手动插入新区间。

class Solution {
public:
    vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
        int l = 0;
        int r = intervals.size();
        int m;
        while(l<r){
            m = l + (r-l)/2;
            if(intervals[m][0]<newInterval[0]) l=m+1;
            else if(intervals[m][0]>newInterval[0]) r=m;
            else{
                if(intervals[m][1]<newInterval[1]) l=m+1;
                else if(intervals[m][1]>newInterval[1]) r=m;
                else return intervals;
            }
        }
        intervals.insert(intervals.begin()+l,newInterval);
        //以下是上一题的部分
        int n = intervals.size();
        vector<int> starts, ends;
        for (int i = 0; i < n; ++i) {
            starts.push_back(intervals[i][0]);
            ends.push_back(intervals[i][1]);
        }
        vector<vector<int>> res;
        sort(ends.begin(),ends.end());
        for (int i = 0, j = 0; i < n; ++i) {
            if (i == n - 1 || starts[i + 1] > ends[i]) {
                res.push_back({starts[j], ends[i]});
                j = i + 1;
            }
        } 
        return res;
    }
};

第二种方法,即忽略上一题的结果,重新编程。
很容易将原区间分成三部分,一是完全小于新区间的区间,二是与新区间有重叠部分的区间,三是完全大于新区间的区间。对于一和三两部分,我们可以不予理会,直接将其准备输出。那么我们只需要将第二部分的区间进行合并即可。
定义索引n,遍历整个集合,对于第一部分和第三部分,将其插入待输出结果。
对于第二部分的区间,利用其数值更新新区间的数组,最后将新区间插入待输出结果。
整个过程不再需要排序,也不需要新的额外空间,时间复杂度O(N),空间复杂度O(1)

class Solution {
public:
    vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
        vector<vector<int>> res;
        if(intervals.size()==0) return res.push_back(newInterval),res;
        int n = 0;
        //所有小于新区间的区间
        while(n<intervals.size()){
            //如果结束点小于新区间起始点
            if(intervals[n][1]<newInterval[0]){
                res.push_back(intervals[n++]);
            }
            else break;
        }
        //计算并插入合并后的区间
        while(n<intervals.size()){
            //如果起始点小于等于新区间结束点,即需要合并
            if(newInterval[1]>=intervals[n][0]){
                //如果起始点小于新区间起始点
                if(intervals[n][0]<newInterval[0]){
                    newInterval[0]=intervals[n][0];
                }
                //如果结束点大于新区间结束点
                if(intervals[n][1]>newInterval[1]){
                    newInterval[1]=intervals[n][1];
                }
                ++n;
            }
            else break;
        }
        res.push_back(newInterval);
        //剩下的区间
        while(n<intervals.size()){
            res.push_back(intervals[n++]);
        }
        return res;
    }
};

最后

以上就是含糊月光为你收集整理的leetcode_57.插入区间的全部内容,希望文章能够帮你解决leetcode_57.插入区间所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部