一、452. 用最少数量的箭引爆气球
题目链接:https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/
文章讲解:https://programmercarl.com/0452.%E7%94%A8%E6%9C%80%E5%B0%91%E6%95%B0%E9%87%8F%E7%9A%84%E7%AE%AD%E5%BC%95%E7%88%86%E6%B0%94%E7%90%83.html
视频讲解:https://www.bilibili.com/video/BV1SA41167xe
1.1 初见思路
- 投影到x轴上,其实就类似看重叠区间如何满足条件
- 按x_start从小到大排序,然后从头开始遍历,每个气球最多可以跟几个重合,重合的就算引爆一次
- 然后引爆过的就都不算了,从引爆过之后的继续遍历
1.2 具体实现
class Solution {public int findMinArrowShots(int[][] points) {Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));int count = 0;//记录准备射的箭的范围int x_start=points[0][0];int x_end = points[0][1];for(int[] x :points){//当前气球范围左边界 <= 射箭范围的右边界,说明可准备缩小射箭左范围(但是遍历的过程就是缩小射箭缩范围)if(x[0]<=x_end){//当前气球范围右边界 >= 射箭范围的右边界,说明范围已覆盖if(x[1]>=x_end){continue;}//当前气球范围右边界 < 射箭范围的右边界,说明可缩小射箭右范围else{x_end = x[1];}}当前气球范围左边界 > 射箭范围的右边界,说明得换新的箭了,更新射箭范围else{count++;x_start = x[0];x_end = x[1];}}return count+1;}
}
1.3 重难点
二、 435. 无重叠区间
题目链接:https://leetcode.cn/problems/non-overlapping-intervals/
文章讲解:https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html
视频讲解:https://www.bilibili.com/video/BV1A14y1c7E1
2.1 初见思路
- 如何模拟出需要考虑的情况
- 肯定跟上一题一样需要进行排序,这题先考虑按右边界进行排序
- 判断两个是否重叠好说,假设两个重叠了,怎么判断他们是否跟第三个重叠?
取 区间1 和 区间2 右边界的最小值,因为这个最小值之前的部分一定是 区间1 和区间2 的重合部分,如果这个最小值也触达到区间3,那么说明 区间 1,2,3都是重合的
2.2 具体实现
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> {
return Integer.compare(a[0], b[0]);
});
int count = 1;
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] < intervals[i - 1][1]) {
intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);
continue;
} else {
count++;
}
}
return intervals.length - count;
}
}
2.3 重难点
- 怎么模拟特殊的场景
三、 763.划分字母区间
题目链接:https://leetcode.cn/problems/partition-labels/
文章讲解:https://programmercarl.com/0763.%E5%88%92%E5%88%86%E5%AD%97%E6%AF%8D%E5%8C%BA%E9%97%B4.html
视频讲解:https://www.bilibili.com/video/BV18G4y1K7d5
3.1 初见思路
- 找到每个字母的最远的下标
- 从第一个字母开始,这个字母从下表0 到 最远的这个为一段,这一段中出现的字母,遍历一遍看他们最远的下标在哪里,这才是真正的一段。
- 从上面真正的一段之后开始找第二段
3.2 具体实现
class Solution {public List<Integer> partitionLabels(String s) {List<Integer> list = new LinkedList<>();int[] edge = new int[26];char[] chars = s.toCharArray();for (int i = 0; i < chars.length; i++) {edge[chars[i] - 'a'] = i;}int idx = 0;//为什么要设置为-1,为了就是在计算第一个的长度时是正确的int lastIndex = -1;for (int i = 0; i < chars.length; i++) {idx = Math.max(idx, edge[chars[i] - 'a']);if (i == idx) {list.add(i - lastIndex);lastIndex = i;}}return list;}
}
3.3 重难点
- 思路比较难想