zoukankan      html  css  js  c++  java
  • LeetCode(57):插入区间

    Hard!

    题目描述:

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

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

    示例 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] 重叠。

    解题思路:

    这道题让我们在一系列非重叠的区间中插入一个新的区间,可能还需要和原有的区间合并,那么我们需要对给定的区间集一个一个的遍历比较,会有两种情况,重叠或是不重叠,不重叠的情况最好,直接将新区间插入到对应的位置即可,重叠的情况比较复杂,有时候会有多个重叠,我们需要更新新区间的范围以便包含所有重叠区间,之后将新区间加入结果res,最后将后面的区间再加入结果res即可。

    具体思路是,用一个变量cur来遍历区间,如果当前cur区间的结束位置小于要插入的区间的起始位置的话,说明没有重叠,则将cur区间加入结果res中,然后cur自增1。直到有cur越界或有重叠,将while循环退出,然后再用一个while循环处理所有重叠的区间,每次取用两个区间起始位置的较小值,和结束位置的较大值来更新要插入的区间,然后cur自增1。直到cur越界或者没有重叠时while循环退出。之后将更新好的新区间加入结果res,再将cur之后的区间再加入结果res中即可。

    C++解法一:

     1 class Solution {
     2 public:
     3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
     4         vector<Interval> res;
     5         int n = intervals.size(), cur = 0;
     6         while (cur < n && intervals[cur].end < newInterval.start) {
     7             res.push_back(intervals[cur++]);
     8         }
     9         while (cur < n && intervals[cur].start <= newInterval.end) {
    10             newInterval.start = min(newInterval.start, intervals[cur].start);
    11             newInterval.end = max(newInterval.end, intervals[cur].end);
    12             ++cur;
    13         }
    14         res.push_back(newInterval);
    15         while (cur < n) {
    16             res.push_back(intervals[cur++]);
    17         }
    18         return res;
    19     }
    20 };

    下面这种方法的思路跟上面的解法很像,只不过没有用while循环,而是使用的是for循环,但是思路上没有太大的区别,变量cur还是用来记录新区间应该插入的位置,稍有不同的地方在于在for循环中已经将新区间后面不重叠的区间也加进去了,for循环结束后就只需要插入新区间即可。

    C++解法二:

     1 class Solution {
     2 public:
     3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
     4         vector<Interval> res;
     5         int n = intervals.size(), cur = 0;
     6         for (int i = 0; i < n; ++i) {
     7             if (intervals[i].end < newInterval.start) {
     8                 res.push_back(intervals[i]);
     9                 ++cur;
    10             } else if (intervals[i].start > newInterval.end) {
    11                 res.push_back(intervals[i]);
    12             } else {
    13                 newInterval.start = min(newInterval.start, intervals[i].start);
    14                 newInterval.end = max(newInterval.end, intervals[i].end);
    15             }
    16         }
    17         res.insert(res.begin() + cur, newInterval);
    18         return res;
    19     }
    20 };

    下面这种解法就是把上面解法的for循环改为了while循环,其他的都没有变。

    C++解法三:

     1 class Solution {
     2 public:
     3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
     4         vector<Interval> res;
     5         int n = intervals.size(), cur = 0, i = 0;
     6         while (i < n) {
     7             if (intervals[i].end < newInterval.start) {
     8                 res.push_back(intervals[i]);
     9                 ++cur;
    10             } else if (intervals[i].start > newInterval.end) {
    11                 res.push_back(intervals[i]);
    12             } else {
    13                 newInterval.start = min(newInterval.start, intervals[i].start);
    14                 newInterval.end = max(newInterval.end, intervals[i].end);
    15             }
    16             ++i;
    17         }
    18         res.insert(res.begin() + cur, newInterval);
    19         return res;
    20     }
    21 };

    如果学过Design Pattern的,对Iterator Pattern比较熟悉的也可应用Iterator来求解,本质还是一样的,只是写法略有不同。

    C++解法四:

     1 class Solution {
     2 public:
     3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
     4         vector<Interval> res;
     5         vector<Interval>::iterator it = intervals.begin();
     6         int cur = 0;
     7         while (it != intervals.end()) {
     8             if (it->end < newInterval.start) {
     9                 res.push_back(*it);
    10                 ++cur;
    11             } else if (it->start > newInterval.end) {
    12                 res.push_back(*it);
    13             } else {
    14                 newInterval.start = min(newInterval.start, it->start);
    15                 newInterval.end = max(newInterval.end, it->end);
    16             }
    17             ++it;
    18         }
    19         res.insert(res.begin() + cur, newInterval);
    20         return res;
    21     }
    22 };
  • 相关阅读:
    ApplicationContext之getBean方法详解
    Windows10终端优化方案:Ubuntu子系统+cmder+oh-my-zsh
    向 Windows 高级用户进阶,这 10 款效率工具帮你开路 | 新手问号
    Ditto —— windows 剪贴板增强小工具(复制粘贴多条记录)
    Service Mesh服务网格:是什么和为什么
    正确理解Spring事务和数据库事务和锁
    Spring中@Transactional事务回滚(含实例详细讲解,附源码)
    五分钟搞清楚MySQL事务隔离级别
    事务并发的问题场景图解
    Spring的事务管理和数据库事务相关知识
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9149303.html
Copyright © 2011-2022 走看看