贪心算法part4
day35-1 ●452. 用最少数量的箭引爆气球
解题思路
贪心:尽量让重叠的气球在一起然后用一个气球去射爆它,就可以用最少的弓箭,局部最优推出全局最优
模拟过程
代码实现
class Solution {
/**
* 时间复杂度 : O(NlogN) 排序需要 O(NlogN) 的复杂度
* 空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间
*/
public int findMinArrowShots(int[][] points) {
if (points.length == 0) {
return 0;
}
// 使用Integer的compare方法不会溢出
Arrays.sort(points, (p1, p2) -> Integer.compare(p1[1], p2[1]));
int result = 1;// points不为空时只需要一支箭
for (int i = 1; i < points.length; i++) {
if (points[i][0] > points[i - 1][1]) {// 气球i和气球i-1,注意这里不是>=
result++;// 需要一支箭
} else {// 气球i和i -1重叠
points[i][1] = Math.min(points[i][1], points[i - 1][1]);//更新多个气球重叠的最小右边界
}
}
return result;
}
}
总结
- 射爆气球后不需要把元素数组移除
- 判断气球重叠与不重叠
- 判断气球重叠后如何判断气球于下一个气球重叠
day35-2 ● 435. 无重叠区间
解题思路
模拟过程
代码实现
class Solution {
/**
* 时间复杂度 : O(NlogN) 排序需要 O(NlogN) 的复杂度
* 空间复杂度 : O(logN) java所使用的内置函数用的是快速排序需要 logN 的空间
*/
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length == 0){
return 0;
}
// 使用Integer的compare方法不会溢出
Arrays.sort(points, (p1, p2) -> Integer.compare(p1[1], p2[1]));
// Arrays.sort(intervals, (p1,p2)->p1[1]-p2[1]);
int count = 0;// 需要移除区间的最小数量
for(int i = 1; i < intervals.length; i++){
if(intervals[i][0] >= intervals[i-1][1]){
// 不做处理
}else{
count++;
intervals[i][1] = Math.min(intervals[i][1],intervals[i - 1][1]);
}
}
return count;
}
}
总结
左边界排序+右边界排序
day35-3 ● 763.划分字母区间
题意
理解思路、模拟过程
代码实现
class Solution {
/**
* 时间复杂度 : O(n)
* 空间复杂度 : O(1),使用的hash数组是固定大小
*/
public List<Integer> partitionLabels(String s) {
int[] hash = new int[26];// i表示字符,hash表示字符出现的最后位置
// 精华部分
for(int i = 0; i < s.length(); i++){// 统计每个字符出现的位置
hash[s.charAt(i) - 'a'] = i;
}
List<Integer> result = new ArrayList<>();
int left = 0;
int right = 0;
for(int i = 0; i < s.length(); i++){
right = Math.max(right, hash[s.charAt(i) - 'a']);
if(i == right){// 找到了最尾位置
result.add(right - left + 1);
left = i + 1;
}
}
return result;
}
}
总结
贪心思想不明显
核心思想是:用最远距离模拟了圈字符的行为