贪心算法part4
贪心算法part4
452. 用最少数量的箭引爆气球 - 力扣(LeetCode)
意外的简单
我的思路:
- 首先将单个气球边界按右升序排序;
- 然后开始打气球,如果下个气球左边界在右边界之内,就一定能被上个气球涵盖;
- 如果涵盖,再重复打下一个气球,直到打不到
- 打不到了,开始新的打气球过程
class Solution {
public int findMinArrowShots(int[][] points) {
Arrays.sort(points, (a, b) -> Integer.compare(a[1], b[1]));
int res = points.length;
for(int i = 0; i < points.length; i++){
int index = i;
while(i < points.length - 1 && points[i + 1][0] <= points[index][1]){
res--;
i++;
}
}
return res;
}
}
tip:
在排序器计算时,出现这样的数据:
[[-2147483646,-2147483645],[2147483646,2147483647]]
那么直接排序,会出现越界错误
Arrays.sort(points, (a, b) -> {
return a[1] - b[1];
});
所以上面题目,使用Integer内置函数compare()
Arrays.sort(points, (a, b) -> Integer.compare(a[1], b[1]));
435. 无重叠区间 - 力扣(LeetCode)
同上,思路上一点点不同
上题求相同区间,本题求不同区间
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> {
if(a[1] == b[1]){
return a[0] - b[0];
}
return a[1] - b[1];
});
int res = 0;
for(int i = 0; i < intervals.length; i++){
int index = i;
while(i < intervals.length - 1 && intervals[index][1] > intervals[i + 1][0]){
res++;
i++;
}
}
return res;
}
}
763. 划分字母区间 - 力扣(LeetCode)
本题和上面两题还是相同的思路,只不过规律隐藏起来了,需要画图找思路(这是做完上面两题后出现的第一感觉)
实际上本题可以很简单
思路:
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。
可以分为如下两步:
- 统计每一个字符最后出现的位置
- 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
![]()
代码:
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> list = new ArrayList<>();
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;
int last = -1;
for(int i = 0; i < chars.length; i++){
idx = Math.max(idx, edge[chars[i] - 'a']);
if(i == idx){
list.add(i - last);
last = i;
}
}
return list;
}
}

浙公网安备 33010602011771号