当前位置: 首页 > news >正文

算法学习-贪心问题(持续更新中)

文章目录

  • 基础知识
  • 相关题目
    • 区间问题
        • 435.无重叠区间
        • 646.最长数对链
        • 452.用最少数量的箭引爆气球

贪心问题没有特别多的套路,大多数思想就是模拟,简单来说就是看到题目觉得不用特别的算法,通过数学归纳法做能行,就采用贪心问题。本文就对相关的贪心问题进行汇总,也把一些类似的思想归下类,供大家学习参考。

本文参考:

代码随想录
用引爆气球贪心思想解决区间问题「图解」

基础知识

「贪心算法」的问题需要满足的性质:

  • 最优子结构:规模较大的问题的解由规模较小的子问题的解组成,规模较大的问题的解只由其中一个规模较小的子问题的解决定;
  • 无后效性:后面阶段的求解不会修改前面阶段已经计算好的结果;
  • 贪心选择性质:从局部最优解可以得到全局最优解。

相关题目

区间问题

心得体会:

  • 在求无重叠区间需要移除的个数时候会从反面考虑,考虑比较好算的无重叠区间有多少个,最后用总数减掉,也不关心重叠区间应该如何删除,当碰到重叠的时候,也只是更新最小右边界。
  • 在求重叠区间的时候都会进行排序,有些题目用来求重叠区间最小数量,如646.最长数对链,有些是来求重叠区间最大数量,如452.用最少数量的箭引爆气球。两面理解起来,排序以后维护最小右边界,不重叠区间最多是通过使右边界最小实现的,而重叠区间最多也是通过尽可能在两个气球右边界的最小值射箭实现的。

435.无重叠区间

这道题要尽可能地在一个时间段内安排多个课程,直观的贪心思想。先排序,然后根据排序结果贪心,尽可能多安排区间分散开来,移除区间的数目就是区间总数目减去不重叠区间的数目。求移除区间数目,可以根据左边界升序排序也可以根据右边界升序排序。

左边界升序排序,参考用引爆气球贪心思想解决区间问题「图解」,其中在原数据上维护更新重叠区间的最小右边界思想值得学习,其中result求的是「不重叠区间的数目」。移除区间的数目就是区间总数目减去不重叠区间的数目,不重叠区间的数目是理论上来说最后会留下来的那些区间,维护更新重叠区间的最小右边界时优先选择重叠的较小边界,从而给后面的区间腾空间,也相当于是多了一个需要移除的区间。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        int len=intervals.length;
        Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
        //intervals[0]是最终答案里的首个元素
        int res=1;
        for(int i=1;i<len;i++){
        	//不重叠区间
            if(intervals[i][0]>=intervals[i-1][1]) res++;
            else{
            	//重叠区间更新右边界
                intervals[i][1]=Math.min(intervals[i-1][1],intervals[i][1]);
            }
        }
        return len-res;
    }
}

右边界升序排列,参考贪心解法其实就是一层窗户纸,戳破了就好了!,同样是找数量最多的不重叠区间,尽可能每次找到最小的右边界,不过这里和上面的区别就是没有针对重叠区间进行更多逻辑处理。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        int len=intervals.length;
        Arrays.sort(intervals,(o1,o2)->o1[1]-o2[1]);
        //intervals[0]是最终答案里的首个元素
        int res=1;
        //右边界升序,维护一个变量right
        int right=intervals[0][1];
        for(int i=1;i<len;i++){
            //与前面区间不重叠的区间>=right
            if(intervals[i][0]>=right){
                res++;
                right=intervals[i][1];
            }
        }
        return len-res;
    }
}

646.最长数对链

这题直接求的是不重叠区间,解法类似上面

class Solution {
    public int findLongestChain(int[][] pairs) {
        int len=pairs.length;
        Arrays.sort(pairs,(o1,o2)->o1[0]-o2[0]);
        int res=1;
        for(int i=1;i<len;i++){
            if(pairs[i][0]>pairs[i-1][1]){
                res++;
            }else{
                pairs[i][1]=Math.min(pairs[i-1][1],pairs[i][1]);
            }
        }
        return res;
    }
}

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

这题类似646.最长数对链,只要重叠区间越多,则箭的数量越少。但是同样的做法,上面是求不重叠区间的数量最多,这里是求重叠的数量最多,在最多之中蕴含着贪心。两面理解起来,排序以后维护最小右边界,不重叠区间最多是通过使右边界最小实现的,而重叠区间最多也是通过尽可能在两个气球右边界的最小值射箭实现的。

class Solution {
    public int findMinArrowShots(int[][] points) {
        int len=points.length;
        Arrays.sort(points,(o1,o2)->Integer.compare(o1[1],o2[1]));
        int end=points[0][1];
        int res=1;
        for(int i=1;i<len;i++){
            //求不重叠区间数目res
            if(points[i][0]>end){
                res++;
                end=points[i][1];
            } 
        }
        return res;
    }
}

相关文章:

  • SpringBoot+Shiro+JWT实现授权
  • 与归并排序相关的一些问题
  • 【C语言拓展】缓冲区、结构体大小计算、命令行参数
  • 《华为数据之道》总结
  • java基于springboot+vue+elementui的会员制在线读书图书购物管理平台
  • python:数据类型、编码方式(base64、utf--8)、python中的进制、\u,\x,0x区别
  • 操作系统中的进程是什么?(详细讲解进程调度相关PCB信息)
  • Java并发 JUC工具类:Semaphore详解
  • Android 开发框架——Glide 图片加载框架
  • CentOS 7 安装教程(基于虚拟机安装)
  • IOC理论
  • nginx官网下载,安装时隐藏版本号、响应头信息、容器信息
  • 【量化交易】 量化因子 风险类因子
  • 基于springboot的张仲景药房(药店)管理系统
  • SpringBoot线上项目隐藏Swagger接口文档
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • crontab执行失败的多种原因
  • css布局,左右固定中间自适应实现
  • HTTP中GET与POST的区别 99%的错误认识
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Javascript弹出层-初探
  • js继承的实现方法
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Python学习之路13-记分
  • rc-form之最单纯情况
  • React Native移动开发实战-3-实现页面间的数据传递
  • tensorflow学习笔记3——MNIST应用篇
  • ucore操作系统实验笔记 - 重新理解中断
  • vue-loader 源码解析系列之 selector
  • Yii源码解读-服务定位器(Service Locator)
  • - 概述 - 《设计模式(极简c++版)》
  • 前端之Sass/Scss实战笔记
  • 双管齐下,VMware的容器新战略
  • 详解移动APP与web APP的区别
  • 新书推荐|Windows黑客编程技术详解
  • 一个SAP顾问在美国的这些年
  • 异步
  • 自制字幕遮挡器
  • #vue3 实现前端下载excel文件模板功能
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • $(selector).each()和$.each()的区别
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (8)STL算法之替换
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (轉貼) 2008 Altera 亞洲創新大賽 台灣學生成果傲視全球 [照片花絮] (SOC) (News)
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET 使用 XPath 来读写 XML 文件
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout