Merge interval and Insert interval

栏目: 编程工具 · 发布时间: 5年前

内容简介:Given a collection of intervals, merge all overlapping intervals.Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].Explanation: Intervals [1,4] and [4,5] are considered overlapping.

题目

Merge interval

Given a collection of intervals, merge all overlapping intervals.

Example 1:

Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]

Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].

Example 2:

Input: [[1,4],[4,5]]
Output: [[1,5]]

Explanation: Intervals [1,4] and [4,5] are considered overlapping.

Insert interval

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:

Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]

Example 2:

Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]

Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].

解法

Merge interval,首先需要对所有的区间进行排序,排序的准则:

  • 先判断区间左侧是否关系:较小者 排序 在前
  • 如果左边界相等,根据右边界决定关系,但是这里将右侧大的往前,其实不重要

然后就遍历数组,进行合并即可:

  • 前面区间和当前区间没有交集,直接将前面区间放入结果
  • 有交集,则进行合并

整体复杂度是: O(NlogN)

Insert interval: 这一题可以偷懒,利用 merge interval 来实现同样的目的。即:

  • 将新区间插入,排序
  • merge

但是这种做法没有充分利用原来区间就已经有序的条件。插入一个新区间,主要就是判断新区间在原来区间中的 位置。

[], [], [], —, [], [], [], — [], []
[], [], [—], [], [], [] — [], []
[], [], [], —, [], [], [—], [], []
[], [], [—], [], [], [—], [], []

上图中的 dash 线表示新区建的左侧和右侧,它与原区间列表存在上述四种关系。对于上述四种关系,我们对于 dash 线前和 dash 线后的区间可以直接复制到结果中,中间直接和新区间 merge 即可。

那么中关系怎么查找呢?可以利用原来数组就是有序的前提进行二分查找。整体复杂度在 O(N)

思路

  • 排序
  • 二分查找边界

代码

class Solution {
private:
    typedef vector<int> V;
    typedef vector<V> VV;
    struct Comp {
        bool operator()(vector<int>& lhs, vector<int>& rhs) {
            if (lhs[0] != rhs[0]) return lhs[0] < rhs[0];
            return lhs[1] < rhs[1];
        }
    };
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end(), Comp());
        int size = intervals.size();
        VV result;
        if (size == 0) return result;
        auto prev = intervals[0];
        for (int i = 1; i < size; ++i) {
            auto& a = intervals[i];
            if (prev[1] < a[0]) {
                result.push_back(prev);
                prev = a;
            } else {
                // prev[1] >= a[0]

                prev[1] = max(prev[1], a[1]);
            }
        }
        result.push_back(prev);
        return result;
    }
};

class Solution {
private:
    typedef vector<int> V;
    typedef vector<V> VV;

    struct Comp {
        bool operator()(vector<int>& lhs, vector<int>& rhs) {
            if (lhs[0] != rhs[0]) return lhs[0] < rhs[0];
            return lhs[1] < rhs[1];
        }
    };


public:
    vector<vector<int>> insert1(vector<vector<int>>& intervals, vector<int>& newInterval) {
        intervals.push_back(newInterval);
        sort(intervals.begin(), intervals.end(), Comp());
        int size = intervals.size();
        VV result;
        auto prev = intervals[0];
        for (int i = 1; i < size; ++i) {
            auto& a = intervals[i];
            if (prev[1] < a[0]) {
                result.push_back(prev);
                prev = a;
            } else {
                // prev[1] >= a[0]

                prev[1] = max(prev[1], a[1]);
            }
        }
        result.push_back(prev);
        return result;
    }
    vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
        VV result;
        int size = intervals.size();
        if (size == 0) {
            result.push_back(newInterval);
            return result;
        }

        // corner case

        if (newInterval[1] < intervals[0][0]) {
            result.push_back(newInterval);
            copy(intervals.begin(), intervals.end(), back_inserter(result));
            return result;
        } else if (newInterval[0] > intervals[size-1][1]) {
            copy(intervals.begin(), intervals.end(), back_inserter(result));
            result.push_back(newInterval);
            return result;
        }

        int low = 0;
        int high = size;
        int target = newInterval[0];
        int pos_b = -1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            auto& h = intervals[mid];
            if (h[0] <= target && h[1] >= target) {
                pos_b = mid; break;
            } else if (h[1] < target) {
                low = mid + 1;
            } else if (h[0] > target) {
                high = mid;
            }
        }
        int low_b = low;
        target = newInterval[1];
        low = 0; high = size;
        int pos_e = -1;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            auto& h = intervals[mid];
            if (h[0] <= target && h[1] >= target) {
                pos_e = mid; break;
            } else if (h[1] < target) {
                low = mid + 1;
            } else if (h[0] > target) {
                high = mid;
            }
        }
        int low_e = low;
        if (pos_e == -1 && pos_b == -1) {
            auto beg = intervals.begin();
            auto end = intervals.begin();
            advance(end, low_b);
            copy(beg, end, back_inserter(result));
            result.push_back(newInterval);
            end = intervals.end();
            advance(beg, low_e);
            copy(beg, end, back_inserter(result));
        } else if (pos_b == -1) {
            auto beg = intervals.begin();
            auto end = intervals.begin();
            advance(end, low_b);
            copy(beg, end, back_inserter(result));
            newInterval[1] = intervals[pos_e][1];
            result.push_back(newInterval);
            advance(beg, min(pos_e + 1, size));
            end = intervals.end();
            copy(beg, end, back_inserter(result));
        } else if (pos_e == -1) {
            auto beg = intervals.begin();
            auto end = intervals.begin();
            advance(end, pos_b);
            copy(beg, end, back_inserter(result));
            newInterval[0] = intervals[pos_b][0];
            result.push_back(newInterval);
            advance(beg, low_e);
            end = intervals.end();
            copy(beg, end, back_inserter(result));

        } else {
            auto beg = intervals.begin();
            auto end = intervals.begin();
            advance(end, pos_b);
            copy(beg, end, back_inserter(result));
            newInterval[0] = intervals[pos_b][0];
            newInterval[1] = intervals[pos_e][1];
            result.push_back(newInterval);
            advance(beg, min(pos_e + 1, size));
            end = intervals.end();
            copy(beg, end, back_inserter(result));
        }
        return result;
    }
};

本文完

Merge interval and Insert interval

This work is licensed under a CC A-S 4.0 International License

.


以上所述就是小编给大家介绍的《Merge interval and Insert interval》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

领域驱动设计

领域驱动设计

埃文斯 / 赵俐、盛海艳、刘霞 / 人民邮电出版社 / 2010-11 / 69.00元

《领域驱动设计:软件核心复杂性应对之道》是领域驱动设计方面的经典之作。全书围绕着设计和开发实践,结合若干真实的项目案例,向读者阐述如何在真实的软件开发中应用领域驱动设计。书中给出了领域驱动设计的系统化方法,并将人们普遍接受的一些最佳实践综合到一起,融入了作者的见解和经验,展现了一些可扩展的设计最佳实践、已验证过的技术以及便于应对复杂领域的软件项目开发的基本原则。《领域驱动设计:软件核心复杂性应对之......一起来看看 《领域驱动设计》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具