LeetCode 57 Insert Interval (Tag:Array Difficulty:Medium)

402 阅读2分钟

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

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

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

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

示例 3:
输入:intervals = [], newInterval = [5,7]
输出:[[5,7]]

示例 4:
输入:intervals = [[1,5]], newInterval = [2,3]
输出:[[1,5]]

示例 5:
输入:intervals = [[1,5]], newInterval = [2,7]
输出:[[1,7]]

链接:leetcode-cn.com/problems/in…

题解

这道题目和上一道leetcode 56 Merge Intervals 其实可以算是基本相同的题目, 但还是有不同的地方. 这道题目我们可以分为以下几步来进行:

  1. 数组已经是有序的了, 我们先要按顺序找到 newInterval 应该插入的位置下标 i, 插入位置 i 的条件是 intervals[i][1] >= newInterval[0]

  2. 在 i 位置插入 newInterval 时, 不能只考虑 newInterval[1] 和 intervals[i][1] 的大小, 因为 newInterval 的第一个元素有可能比 intervals[i] 的第一个元素小, 这是和 leetcode 56 题不同的点, 因为 56 题中所有的数组事先我们按照第一个元素排序了. 而这道题插入时, 我们并不能保证 newInterval[0] 比 intervals[i][0] 要大, 因此一定要选出两者的最小值作为左边界, 向右找到右边界, 更新 newInterval 的两个元素. 然后插入结果数组.

  3. 插入了 newInterval 数组之后, intervals 剩余的数组均是有序的不相交的数组, 依次插入结果数组即可.

对第 2 步不是很理解的同学可以对照着下面的代码来理解.

时间复杂度 O(n), 空间复杂度 O(1)

/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
var insert = function(intervals, newInterval) {
    const n = intervals.length
    let i = 0
    let ans = []
    while (i < n && intervals[i][1] < newInterval[0]) {
        ans.push(intervals[i])
        ++i
    }

    
    while (i < n && intervals[i][0] <= newInterval[1]) {
        newInterval[0] = Math.min(newInterval[0], intervals[i][0])
        newInterval[1] = Math.max(newInterval[1], intervals[i][1])
        ++i
    }
    ans.push(newInterval)
    
    while (i < n) {
        ans.push(intervals[i])
        ++i
    }
    return ans
};