这是我参与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 其实可以算是基本相同的题目, 但还是有不同的地方. 这道题目我们可以分为以下几步来进行:
-
数组已经是有序的了, 我们先要按顺序找到 newInterval 应该插入的位置下标 i, 插入位置 i 的条件是 intervals[i][1] >= newInterval[0]
-
在 i 位置插入 newInterval 时, 不能只考虑 newInterval[1] 和 intervals[i][1] 的大小, 因为 newInterval 的第一个元素有可能比 intervals[i] 的第一个元素小, 这是和 leetcode 56 题不同的点, 因为 56 题中所有的数组事先我们按照第一个元素排序了. 而这道题插入时, 我们并不能保证 newInterval[0] 比 intervals[i][0] 要大, 因此一定要选出两者的最小值作为左边界, 向右找到右边界, 更新 newInterval 的两个元素. 然后插入结果数组.
-
插入了 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
};