985 字
5 分钟
LeetCode刷题(插入区间、最少数量的箭引爆气球)

插入区间#

题目描述#

给你一个 无重叠的 *,*按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。

intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。

返回插入之后的 intervals

示例 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 int[][] insert(int[][] intervals, int[] newInterval) {
        if(intervals == null || intervals.length == 0) {
            return new int[][]{newInterval};
        }
        List<int[]> result = new ArrayList<>();
        int index = -1;
        for(int i = 0; i < intervals.length; i++) {
            int[] range = intervals[i];
            if(range[0] >= newInterval[0]) {
                index = i;
                break;
            }
        }
        if(newInterval[0] > intervals[intervals.length - 1][0]) {
            index = -2;
        }

        if(index == -1) {
            result.add(newInterval);
        }

        for(int i = 0; i < intervals.length; i++) {
            if(i == index) {
                if(result.isEmpty() || newInterval[0] > result.get(result.size() - 1)[1]) {
                    result.add(newInterval);
                } else {
                    int[] target = result.get(result.size() - 1);
                    target[1] = Math.max(target[1], newInterval[1]);
                }
            }

            if(result.isEmpty() || intervals[i][0] > result.get(result.size() - 1)[1]) {
                result.add(intervals[i]);
            } else {
                int[] target = result.get(result.size() - 1);
                target[1] = Math.max(target[1], intervals[i][1]);
            }
        }
        if(index == -2) {
            if(result.isEmpty() || newInterval[0] > result.get(result.size() - 1)[1]) {
                    result.add(newInterval);
                } else {
                    int[] target = result.get(result.size() - 1);
                    target[1] = Math.max(target[1], newInterval[1]);
                }
        }
        int[][] ans = new int[result.size()][2];
        for(int i = 0; i < result.size(); i++) {
            ans[i] = result.get(i);
        }
        return ans;
    }
}

通过较为简单的方式实现

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        List<int[]> result = new ArrayList<>();
        int i = 0;
        int n = intervals.length;
        
        // 1. 添加所有结束时间小于新区间开始时间的区间
        while (i < n && intervals[i][1] < newInterval[0]) {
            result.add(intervals[i]);
            i++;
        }
        
        // 2. 合并所有与新区间重叠的区间
        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++;
        }
        result.add(newInterval);
        
        // 3. 添加剩余区间
        while (i < n) {
            result.add(intervals[i]);
            i++;
        }
        
        return result.toArray(new int[result.size()][]);
    }
}

最少数量的箭引爆气球#

题目描述#

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [xstart, xend] 表示水平直径在 xstartxend之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstartxend, 且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points返回引爆所有气球所必须射出的 最小 弓箭数

示例 1:

输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。

示例 2:

输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。

示例 3:

输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:气球可以用2支箭来爆破:
- 在x = 2处发射箭,击破气球[1,2]和[2,3]。
- 在x = 4处射出箭,击破气球[3,4]和[4,5]。

题解#

先进行按照起始进行从小到大的排序,如果当前区间的左边小于上一个区间的右边界,代表这两个区间重合,可以一并射穿,我们把区间设置为交集供下一个区间判断是否可以合并

class Solution {
    public int findMinArrowShots(int[][] points) {
        if(points.length == 0) {
            return 0;
        }
        Arrays.sort(points, (p1, p2) -> Integer.compare(p1[0], p2[0]));
        int n = points.length;
        for(int i = 1; i < points.length; i++) {
            if(points[i][0] <= points[i - 1][1]) {
                n--;
                points[i][0] = Math.max(points[i][0], points[i - 1][0]);
                points[i][1] = Math.min(points[i][1], points[i - 1][1]);
            }
        }
        return n;
    }
}
LeetCode刷题(插入区间、最少数量的箭引爆气球)
https://thrinisty.github.io/Blog/posts/leetcode刷题插入区间最少数量的箭引爆气球/
作者
Thrinisty
发布于
2025-11-05
许可协议
CC BY-NC-SA 4.0