leetcode刷题day30|贪心算法Part04重叠区间问题(452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间)

前言:今天的三道题目都是重叠区间的问题。

452. 用最少数量的箭引爆气球

思路:局部最优:当气球出现重叠,一起射,所用弓箭最少;

全局最优:把所有气球射爆所用弓箭最少。

按照起始位置排序,如果气球重叠了,重叠气球中右边边界的最小值之前的区间一定需要一个弓箭。

注意:这个解法的以巧妙之处是一直在比较当前气球的左边界和前一个气球的右边界;如果当前气球的左边界大于前一个气球的右边界,则需要多加一支箭;否则的话,就更新当前气球的右边界为两个气球右边界较短的那一个,再去进行比较,看看是不是还有重叠的气球。

代码如下:

java 复制代码
class Solution {
    public int findMinArrowShots(int[][] points) {
        if(points.length==0) return 0;
        int result=1;
        Arrays.sort(points,(a,b)->Integer.compare(a[0],b[0]));
        for(int i=1;i<points.length;i++){
            if(points[i][0]>points[i-1][1]) result++;
            else points[i][1]=Math.min(points[i][1],points[i-1][1]);
        }
        return result;
    }
}

454. 无重叠区间

思路:这个题和气球题的思路差不多,先根据左边界的值进行排序,遍历i的左边界和i-1的右边界,如果i的左边界小于i-1的右边界,需要删除的区间数加一,并将i和i-1中较小的右边界赋值给i的右边界(贪心:尽量留下右边界小的,减少重叠的概率)。

注意:这个题有一个和气球题不同的点,气球打破之后就没有了且要求重叠区间,因此可以将i和i-1中较小的右边界赋值给i的右边界;但这个题

代码如下:

java 复制代码
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if(intervals.length<=1) return 0;
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        int result=0;
        for(int i=1;i<intervals.length;i++){
            if(intervals[i][0]<intervals[i-1][1]){
                result++;
                intervals[i][1]=Math.min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return result;
    }
}

763.划分字母区间

这个题目不太有思路。看题解发现在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。

步骤如下:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点,记录该区间的长度。

代码如下:

java 复制代码
class Solution {
    public List<Integer> partitionLabels(String s) {
        int[] edge=new int[26];
        LinkedList<Integer> result=new LinkedList<>();
        for(int i=0;i<s.length();i++){
            edge[s.charAt(i)-'a']=i;
        }
        int idx=0;
        int last=-1;
        for(int i=0;i<s.length();i++){
            idx=Math.max(edge[s.charAt(i)-'a'],idx);
            if(idx==i){
                result.add(i-last);
                last=i;
            }
        }
        return result;
    }
}
相关推荐
დ旧言~几秒前
专题八:背包问题
算法·leetcode·动态规划·推荐算法
_WndProc18 分钟前
C++ 日志输出
开发语言·c++·算法
努力学习编程的伍大侠31 分钟前
基础排序算法
数据结构·c++·算法
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jasmine_llq1 小时前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
Lenyiin2 小时前
01.02、判定是否互为字符重排
算法·leetcode
鸽鸽程序猿2 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表