2023-04-24 算法面试中常见的贪心算法问题

news2024/9/22 4:02:18

贪心算法

1 贪心选择例题

455.饼干分配

假设你想给小朋友们饼干。每个小朋友最多能够给一块儿饼干。每个小朋友都有一个“贪心指数”,称为g(i),g(i)表示的是这名小朋友需要的饼干大小的最小值。同时,每个饼干都有一个大小值s(i)。如果s(j) >= g(i),我们将饼干j分给小朋友i后,小朋友就会很开心。给定数组s和g,问如何分配饼干,能更让最多的小朋友开心。
如 g = [1, 2, 3], s = [1, 1],结果为1
如 g = [1, 2], s = [1, 2, 3],结果为2

代码见455. 分发饼干

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int gi = g.length - 1;
        int si = s.length - 1;
        int res = 0;
        while (gi >= 0 && si >= 0) {
            if (s[si] >= g[gi]) {
                si--;
                gi--;
                res++;
            } else {
                gi--;
            }
        }
        return res;
    }
}

392.判断子序列

class Solution {
    public boolean isSubsequence(String s, String t) {
        int si = 0, ti = 0;
        while (si < s.length() && ti < t.length()) {
            if (s.charAt(si) == t.charAt(ti)) {
                si++;
                ti++;
            } else {
                ti++;
            }
        }
        return si == s.length();
    }
}

2 贪心算法与动态规划的关系

每次选择中,每个区间的结尾很重要,结尾越小,留给了后面越大的空间,后面越有可能容纳更多空间区间

依据上面的思想,设计出地贪心算法如下:
按照区间的结尾排序,每次选择结尾最早地、且和前一个区间不重叠的区间

动态规划实现

参考最长上升子序列问题的求解

LIS(i) = max( 1 + LIS(j) if nums[i] > nums[j] )
         j<i

上面表达式的含义:从i处往前遍历,遍历到的位置下标为j(j<i),如果nums[j]小于nums[i],且LIS[j]的值不小于LIS[i],则把LIS[i]的值更新为LIS[j]+1,否则保持LIS[i]的值不变,核心伪代码如下:

// 第1个元素不用考虑了,其最长子序列一定是1,已经初始化好了
for (int i = 1; i < nums.length; i++) {
    for (int j = 0; j < i; j++) {
        if (nums[j] < nums[i]) {
            // 如果i前面的值有大于i处的值的,更新子序列长度
            // memo[i]表示当前i处的子序列长度,1+memo[i]表示考虑j的情况下最长子序列长度加1
            // memo[i]在 `j in 0~i`的循环中可能已经被跟新多次了,不再是初始值1了
            memo[i] = Math.max(memo[i], 1 + memo[j]);
        }
    }
}

完整实现如下:

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        // 先转换成List,注意每个interval都是个只有俩元素的数组
        List<int[]> intervalList = new ArrayList<>(Arrays.asList(intervals));
        // 自定义比较器,先比较开头,谁大谁靠后,开头相等地话就看结尾,谁大谁靠后
        intervalList.sort((interval1, interval2) -> {
            if (interval1[0] != interval2[0]) {
                return interval1[0] - interval2[0];
            }
            return interval1[1] - interval2[1];
        });
        // 借鉴最长公共子序列的思想.
        // memo[i]表示用使用intervals[0...i]的区间能构成的最长不重叠区间序列
        int[] memo = new int[intervalList.size()];
        Arrays.fill(memo, 1);
        for (int i = 1; i < intervals.length; i++) {
            for (int j = 0; j < i; j++) {
                // 从i向前遍历,如果i前面找到一个区间的尾部比i所在的区间头部还小,说明找到了一个不重叠区间
                if (intervalList.get(i)[0] >= intervalList.get(j)[1]) {
                    memo[i] = Math.max(memo[i], 1 + memo[j]);
                }
            }
        }
        // 取出最大的不重叠子区间个数
        int res = 0;
        for (int num : memo) {
            if (num > res) {
                res = num;
            }
        }
        // 题目要地是删除多少个区间可以得到最大的不重叠的子区间,所以要用区间总个数减去最多的不重叠子区间个数
        return intervalList.size() - res;
    }
}

贪心算法实现

每次选择结尾最早地、且和前一个区间不重叠的区间

class 贪心算法实现 {
    public int eraseOverlapIntervals(int[][] intervals) {
        if(intervals.length == 0){
            return 0;
        }
        // 先转换成List,注意每个interval都是个只有俩元素的数组
        List<int[]> intervalList = new ArrayList<>(Arrays.asList(intervals));
        // 自定义比较器,先比较结尾,谁大谁靠后,结尾相等地话就看开头,谁大谁靠后
        intervalList.sort((interval1, interval2) -> {
            if (interval1[1] != interval2[1]) {
                return interval1[1] - interval2[1];
            }
            return interval1[0] - interval2[0];
        });
        // 贪心算法思路:不断选取结尾最早且区间和前面不重合的区间
        // 第一个区间先选上
        int res=1;
        // i前面的区间在intervalList中的下标
        int pre = 0;
        for (int i = 1; i < intervalList.size(); i++) {
            // 前面区间的结尾比后面区间的开头还小,说明找到了一个不重叠区间
            if (intervalList.get(pre)[1] <= intervalList.get(i)[0]){
                res++;
                pre = i;
            }
        }
        return intervalList.size() - res;
    }
}

3 贪心选择的适用性验证与性质

验证问题是否能用贪心算法:反证法

贪心算法的每个步骤不能影响后面的步骤,看问题是否适用于贪心算法可以尝试能否举出返利说明贪心算法中间步骤的错误性。下面就是举反例证明当前问题贪心算法是否适用的例子
![举反例证明当前问题贪心算举反例证明当前问题贪心算法是否适用例,如何验证问题能否用贪心算法?
使用归纳法:假设贪心算法不正确,不断向后推导,如果能推导出和已知矛盾的结论,就说明贪心算法是适用地

贪心算法的性质

给定一组区间,问最多保留多少个区间,可以让这些区间之间互相不重叠。

贪心算法:按照区间的结尾排序,每次选择结尾最早的,且和前一个区间不重叠的区间
某次选择的是 [s(i), f(i)];其中f(i)是当前所有选择中结尾最早的

假设这个选择不是最优的。也就是说,如果这个问题的最优解为k,则这个选择得到的解,最多为k-1。
假设最优解在这一步选择 [s(j), f(j)] 中,f(j) > f(i)。
此时,显然可以将[s(i), f(i)]替换[s(j),f(j)],而不影响后续的区间选择。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fy8XEcu6-1682350202048)(src贪心算法的性质]sr贪心算法的性质2质证明

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bcphEBAt-1682350202049)(s贪心算法的性质证明]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

转换json格式的日期为Javascript对象的函数

项目中碰到了用jQuery从后台获取的json格式的日期的字符串&#xff0c;需要将此字符串转换成JavaScript的日期对象。 代码如下: //转换json格式的日期&#xff08;如&#xff1a;{ServerDatetime:"\/Date(1278930470649)\/"}&#xff09;为Javascript的日期对象 fu…

【离散系统】传递函数和状态空间方程离散化

本文如有错误&#xff0c;恳请指正。 目录 离散系统 采样控制系统 数字控制系统 信号采样 采样定理&#xff08;香农定理&#xff09; 信号保持—零阶保持器 Z变换 Z 变换方法 级数求和法 部分分式法 基本定理 Z反变换 Z反变换方法 长除法 部分分式法&#xff0…

hook函数,toRef家族

自定义hook函数 什么是hook?——本质是一个函数&#xff0c;把setup函数中使用的组合式API 进行了封装。 类似于vue2.x中的mixin。 自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂。 定义钩子&#xff1a; 使用钩子 toRef&#xff0c;toRefs 作用:创建一个ref对象…

WinScope实现录制视频与是Timeline时间轴同步设置方法-千里马framework车载手机系统开发实战

hi&#xff0c;粉丝朋友们&#xff01; 背景&#xff1a; 今天来分享一个粉丝朋友提出的问题&#xff0c;那就是他在学习wms课程时候有用到winscope工具&#xff0c;提出一个疑问&#xff0c;就是google官网说的有录屏可以结合起来一起看。具体如下&#xff1a; 其实这个以…

Vue 手搓轮播效果

tiptop: 为啥需要写这个功能&#xff0c;因为我遇到了每个轮播层内要放3个左右的商品块&#xff0c;如果使用element自带的轮播就需要将一维数组切成二维数组&#xff0c;导致处理一些情况下就会变得很麻烦&#xff0c;当然那种我也写了如果你们有需要&#xff0c;在下方留言我…

柳永8首绝美词句

他是白衣卿相&#xff0c;是才子词人。 他有傲人的才华&#xff0c;却仕途失意。 他眠花宿柳&#xff0c;写下流传千古的词章。 他是才子柳永。 今天&#xff0c;给大家介绍他的8首词&#xff0c;体会柳永的人生起伏。 1、《雨霖铃 寒蝉凄切》 寒蝉凄切&#xff0c;对长亭晚…

Kafka 安装部署-单节点

Kafka强依赖ZK&#xff0c;如果想要使用Kafka&#xff0c;就必须安装ZK&#xff0c;Kafka中的消费偏置信息、kafka集群、topic信息会被存储在ZK中。有人可能会说我在使用Kafka的时候就没有安装ZK&#xff0c;那是因为Kafka内置了一个ZK&#xff0c;一般我们不使用它。 部署说明…

Yuzuki Lizard 全志V851S开发板 –移植 QT5.12.9教程

本文转载自&#xff1a;https://forums.100ask.net/t/topic/3027 移植 QT5 教程 &#xff08;此教程基于docker版V851S开发环境&#xff09; docker pull registry.cn-hangzhou.aliyuncs.com/gloomyghost/yuzukilizard 编译依赖 apt-get install repo git gcc-arm-linux-gn…

用户订阅付费如何拆解分析?看这篇就够了

会员制的订阅付费在影音娱乐行业中已相当普及&#xff0c;近几年&#xff0c;不少游戏厂商也开始尝试订阅收费模式。在分析具体的用户订阅偏好以及订阅付费模式带来的增长效果时&#xff0c;我们常常会有这些疑问&#xff1a; 如何从用户的整体付费行为中具体拆解订阅付费事件…

Numpy从入门到精通——数组变形|合并数组

这个专栏名为《Numpy从入门到精通》&#xff0c;顾名思义&#xff0c;是记录自己学习numpy的学习过程&#xff0c;也方便自己之后复盘&#xff01;为深度学习的进一步学习奠定基础&#xff01;希望能给大家带来帮助&#xff0c;爱睡觉的咋祝您生活愉快&#xff01; 这一篇介绍《…

SLAM论文速递:SLAM—— 流融合:基于光流的动态稠密RGB-D SLAM—4.25(2)

论文信息 题目&#xff1a; FlowFusion:Dynamic Dense RGB-D SLAM Based on Optical Flow 流融合:基于光流的动态稠密RGB-D SLAM论文地址&#xff1a; https://arxiv.org/pdf/2003.05102.pdf发表期刊&#xff1a; 2020 IEEE International Conference on Robotics and Automa…

【Spring Cloud】Spring Cloud 是什么?

文章目录 前言一、子项目二、常用组件三、把 Spring Cloud 官方、Netflix、Alibaba 三者整理成如下表格&#xff1a; 前言 Spring 以 Bean&#xff08;对象&#xff09; 为中心&#xff0c;提供 IOC、AOP 等功能。Spring Boot 以 Application&#xff08;应用&#xff09; 为中…

Python小姿势 - Python操作Excel表格数据

Python操作Excel表格数据 在日常工作中&#xff0c;我们经常会遇到一些需要对表格数据进行处理的情况&#xff0c;比如&#xff1a;数据清洗、数据分析、数据可视化等。对于这些任务&#xff0c;我们可以使用Python来进行操作。 在Python中操作Excel表格数据&#xff0c;我们可…

electron+vue3全家桶+vite项目搭建【13】封装加载进度显示,新建窗口 演示主进程与渲染进程通信

文章目录 引入实现效果演示&#xff1a;1.封装新建窗口工具2.测试新建窗口3.封装进度条加载4.测试进度条加载 引入 这里我们通过封装electron的工具类来演示electron中的主进程和渲染进程利用ipc进行通信 demo项目地址 electron官方文档ipc通信 实现效果演示&#xff1a; …

通过注册表设置远程桌面的配置

***************************修改远程终端端口号*************************** [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Terminal Server\Wds\rdpwd\Tds\tcp] "PortNumber"dword:00000d3d [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Terminal Ser…

代码优雅之道——如何干掉过多的if else

1、前言 注意标题是过多的&#xff0c;所以三四个就没必要干掉了。实际开发中我们经常遇到判断条件很多的情况&#xff0c;比如下图有20多种情况&#xff0c;不用想肯定是要优化代码的&#xff0c;需要思考的是如何去优化&#xff1f; 网上很多说用switch case啊&#xff0c;首…

算法刷题|198.打家劫舍、213.打家劫舍Ⅱ、337.打家劫舍Ⅲ

打家劫舍 题目&#xff1a;你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定…

【社区图书馆】Fundamentals Of Computer Graphics——The beginning of computer graphics

目录 English 中文 English "Fundamentals Of Computer Graphics" is a classic textbook on computer graphics, also known as the "Tiger Book". It is considered one of the best introductory texts in the field of computer graphics. The book …

1分钟搭建自己的GPT网站

如果觉得官方免费的gpt&#xff08;3.5&#xff09;体验比较差&#xff0c;总是断开&#xff0c;或者不会fanqiang&#xff0c;那你可以自己搭建一个。但前提是你得有gpt apikey。年初注册的还有18美金的额度&#xff0c;4.1号后注册的就没有额度了。不过也可以自己充值。 有了…

【Redis】Redis事务

介绍 可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c; 按顺序地串行化执行而不会被其他命令插入一个队列中&#xff0c;一次性、顺序性、排他性的执行一系列命令没有隔离级别的概念&#xff0c;没有脏读、不可重复读等。 …