贪心算法入门(三)

news2024/12/25 0:24:29

相关文章

贪心算法入门(一)-CSDN博客

贪心算法入门(二)-CSDN博客

1.什么是贪心算法?

        贪心算法是一种解决问题的策略,它将复杂的问题分解为若干个步骤,并在每一步都选择当前最优的解决方案,最终希望能得到全局最优解。这种策略的核心在于“最优”二字,意味着我们追求的是以最少的时间和精力,快速获得正确的结果。

        然而,“希望得到全局最优解”就表示贪心算法并不意味着一定能得到全局最优解。实际上,并不是所有问题都可以通过贪心策略解决。为了确保贪心策略的有效性,需要对其进行严格的证明。而且,不同的问题往往需要采用不同的贪心策略。

        如果你觉得这一点仍然比较抽象,接下来我将通过5道具体的例题来详细说明贪心算法的应用及其背后的思路。

2. 按身高排序

2418. 按身高排序 - 力扣(LeetCode)

这道题要求很简单,根据身高排序,但是输出的是名字。对身高排序很简单,可以直接用sort,但是真正需要排序的数组是name姓名数组。但是比较方法又是根据身高比较的,所以想一个办法绑定这两个数组。可以使用一个中间数组index下标数组,里面存放每个下标,然后对index数组排序,比较的规则可以自己写入用身高大小排序。排序之后的index数组就是按照身高下标来排序的了,比如index[0]的值为2就表示身高最高的人的下标为2,那么应该先输出name[2]的值。

2.1 代码实现

class Solution {
    public String[] sortPeople(String[] names, int[] heights) {
        int n = names.length;
        Integer[] index = new Integer[n];
        for(int i = 0; i < n; i++) index[i] = i;
        Arrays.sort(index, (a, b) -> heights[b] - heights[a]);
        String[] ret = new String[n];
        for(int i = 0; i < n; i++) ret[i] = names[index[i]];
        return ret;
    }
}

3. 优势洗牌

870. 优势洗牌 - 力扣(LeetCode)

题目解析:可以任意重组nums1的顺序,并且该顺序可以让nums1和nums2依次比较大小时,nums1优胜的次数更多。

该题的贪心策略跟田忌赛马很像,可以对nums1和nums2数组都按从小到大排序。然后再依次比较如果第一个位置nums1就小于nums2,相当于两个数组最小的值比较nums1都输了,此时把这个最小的数去匹配nums2最大的数,然后nums1再用下一个数继续比较nums2的数。依次类推。这样做的好处就是知道nums1最小的数已经对于nums2中的任何数字都取得不了优胜了,那么就不要选择匹配当前nums2最小的数,选择匹配最大的数,这样就可以留着nums1最大的数去匹配nums2前面的数,增大优胜的概率。

上图为整个逻辑流程图,依次扫描nums1数组的每个数,每次扫描都可以确定扫描的数匹配nums2的哪一个数。匹配规则为当前nums1扫描的数小于等于nums2[left]的数就让其匹配nums2[right]的数,否则匹配nums2[left]的数。

还需要注意的一点,这样的做法并不是最终答案,因为我们只能改变nums1的顺序不能改变nums2的,要根据原有的nums2的顺序,去填入nums1的值。所以该题依然需要一个中间变量下标数组去绑定两个数组下标的对应关系。

3.1 代码实现

class Solution {
    public int[] advantageCount(int[] nums1, int[] nums2) {
       int n = nums1.length;
       Integer[] index = new Integer[n];
       for(int i = 0; i < n; i++) index[i] = i;
       Arrays.sort(index, (i, j) -> nums2[i] - nums2[j]);
       Arrays.sort(nums1);
       int[] ret = new int[n];
       int right = n - 1, left = 0;
       for(int x : nums1){
         if(x  > nums2[index[left]]) ret[index[left++]] = x; // index[left]表示当前nums2最小值的下标
         else ret[index[right--]] = x; // index[right]表示当前nums2最大值的下标
       }
       return ret;
    }
}

4. 最长回文串

409. 最长回文串 - 力扣(LeetCode)

这道题要构造回文串,构成回文串有两种可能,一种是回文串中每个字母都是偶数,这样可以对称的分为两边构成回文,还有一种是偶数对称之后,中间单夹一个任意字母。

故这道题的贪心思路很简单,首先就需要统计字符串中每个字母的个数,这里可以有一个优化的小tip就是不适用map表来统计,而是使用数组来代替map表,因为大小字母的asc码值最大也不超过126,所以新建一个大小为126的int数组就可以将所有字母的个数统计完整。

继续优化:可以在循环字符串时一边统计字母个数时一边更新长度,因为只要统计到当前字母的个数等于2了,就可以把它往回文串里面加,让ret长度加2,然后再让hash表中该字母的个数重置为0。现在还有一个问题,当循环完成之后就是最终答案了吗?其实不是,因为循环里面统计长度的规则只考虑了偶数回文串的情况,这时需要判断ret的值是否小于字符串s的长度,如果小于说明还可以有单的字母加进去,这个字母可以是字符串中剩下字母中的任何一个。那么此时更新ret加1,否则直接返回ret。

4.1 代码实现

class Solution {
    public int longestPalindrome(String s) {
        int[] hash = new int[126];
        char[] ss = s.toCharArray();
        int ret = 0;
        for(char ch : ss){
            hash[ch] += 1;
            if(hash[ch] == 2){
                ret += 2;
                hash[ch] = 0;
            }
        }
        return ret < s.length() ? ret + 1 : ret;
    }
}

5. 增减字符串

942. 增减字符串匹配 - 力扣,然后(LeetCode)

 题目解析:输出的int数组中每个位置的值都是由0-n组成的,n为s字符串的长度。每个位置的值要根据s字符串的字母确定,例如示例1中,s字符串的长度为4,所以最终返回的int数组长度为n + 1。s字符串中第一个字母是I表示,int数组要进行上升,比如0到4就是一个上升。第二个字母是D表示要下降,4到1就是下降。以此类推。

贪心策略,遇到字母是I上升趋势的时候,确定当前int数组的数字为0-n中剩下可以挑选的数字中的最小的一个,因为选择最小的一个下一个位置的数字就只用受下一个字母的条件限制,而不用管上一个字母的限制,因为此时的任何数字都会比最小的数字大。拿示例1举例,第一个字母是I,如果此时int数组不选择0选择其他数字比如1。第二个字母是D,选择的数字不能是0和1,1被选过了,也不能选0因为0比1小,不满足第一个字母的I。但是如果第一次选择0,第二次选择数字的时候就不用考虑前一个字母的条件,因为剩下的数字1-n都比0大,所以只用考虑第二个字母D下降,同理此时应该选择最大的数字n,因为下一个选择的数字都可以从剩下的数中任意挑选,并且肯定满足条件。

5.1 代码实现

class Solution {
    public int[] diStringMatch(String s) {
        int n = s.length();
        int[] ret = new int[n + 1];
        int left = 0, right = n;
        for(int i = 0; i < n; i++){
            if(s.charAt(i) == 'I') ret[i] = left++;
            else ret[i] = right--;
        }
        ret[n] = left;
        return ret;
    }
}

6. 分发饼干

455. 分发饼干 - 力扣(LeetCode)

 这道题跟优势洗牌思路一样,就是对两个数组进行排序,然后依次比较,如果不满足当前孩子的胃口就让饼干数组往后一位继续比较知道满足为止。贪心的策略就是尽量用小的饼干尺寸去满足孩子胃口。

6.1 代码实现

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g); Arrays.sort(s);
        int ret = 0;
        for(int i = 0, j = 0; i < g.length && j < s.length; j++){
            if(s[j] >= g[i]){
                i++; ret++;
            }
        }
        return ret;
    }
}

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

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

相关文章

企业知识中台:构建智慧企业的核心

在当今数字化时代&#xff0c;企业知识中台已成为构建智慧企业的核心。它不仅是企业知识资产的集中地&#xff0c;也是推动企业创新和提高决策效率的关键。本文将分为四个部分&#xff0c;详细探讨知识中台的概念、重要性、构建步骤以及如何利用HelpLook工具搭建企业知识库。 …

基于Spring Boot的在线性格测试系统设计与实现(源码+定制+开发)智能性格测试与用户个性分析平台、在线心理测评系统的开发、性格测试与个性数据管理系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

机器学习 ---线性回归

目录 摘要&#xff1a; 一、简单线性回归与多元线性回归 1、简单线性回归 2、多元线性回归 3、残差 二、线性回归的正规方程解 1、线性回归训练流程 2、线性回归的正规方程解 &#xff08;1&#xff09;适用场景 &#xff08;2&#xff09;正规方程解的公式 三、衡量…

shell脚本(1)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;shell脚本&#xff08;1&#xff09;脚本创建执行与变量使用_哔哩哔哩_bilibili 本文主要讲解shell脚本的创建、执行和变量的使用。 一、脚本执行…

测试实项中的偶必现难测bug--互斥逻辑异常

问题: 今天线上出了一个很奇怪的问题,看现象和接口是因为数据问题导致app模块奔溃 初步排查数据恢复后还是出现了数据重复的问题,查看后台实际只有一条数据,但是显示在app却出现了两条一模一样的置顶数据 排查: 1、顺着这个逻辑,我们准备在预发复现这个场景,先是cop…

解决MySQL中整型字段条件判断禁用不生效的问题

MySQL中&#xff0c;当尝试将整数与字符串进行比较时&#xff0c;数据库可能会尝试将字符串转换为整数。在这种情况下&#xff0c;空字符串会被转换为整数0&#xff0c;所以0 ! 会被解释为0 ! 0&#xff0c;结果自然是false。 在开发过程中&#xff0c;我们经常需要对数据库中的…

Flink1.19编译并Standalone模式本地运行

1.首先下载源码 2.本地运行 新建local_conf和local_lib文件夹&#xff0c;并且将编译后的文件放入对应的目录 2.1 启动前参数配置 2.1.2 StandaloneSessionClusterEntrypoint启动参数修改 2.1.3 TaskManagerRunner启动参数修改 和StandaloneSessionClusterEntrypoint一样修改…

创建vue插件,发布npm

开发步骤&#xff1a;1.创建一个vue项目&#xff0c;2.开发一个组件。 3.注册成插件。 4.vite和package.json配置。5.发布到npm &#xff11;.创建一个vue项目 npm create vuelatest 生成了vue项目之后&#xff0c;得到了以下结构。 在src下创建个plugins目录。用于存放开发的…

【深度学习】LSTM、BiLSTM详解

文章目录 1. LSTM简介&#xff1a;2. LSTM结构图&#xff1a;3. 单层LSTM详解4. 双层LSTM详解5. BiLSTM6. Pytorch实现LSTM示例7. nn.LSTM参数详解 1. LSTM简介&#xff1a; LSTM是一种循环神经网络&#xff0c;它可以处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM通…

Queuing 表(buffer表)的优化实践 | OceanBase 性能优化实践

案例问题描述 该案例来自一个金融行业客户的问题&#xff1a;他们发现某个应用对一个数据量相对较小的表&#xff08;仅包含数千条记录&#xff09;访问时&#xff0c;频繁遇到性能下降的情况。为解决此问题&#xff0c;客户向我们求助进行分析。我们发现这张表有频繁的批量插…

【视觉SLAM】4b-特征点法估计相机运动之PnP 3D-2D

文章目录 1 问题引入2 求解P3P 1 问题引入 透视n点&#xff08;Perspective-n-Point&#xff0c;PnP&#xff09;问题是计算机视觉领域的经典问题&#xff0c;用于求解3D-2D的点运动。换句话说&#xff0c;当知道n个3D空间点坐标以及它们在图像上的投影点坐标时&#xff0c;可…

SpringBoot多环境+docker集成企业微信会话存档sdk

SpringBoot多环境docker集成企业微信会话存档sdk 文章来自于 https://developer.work.weixin.qq.com/community/article/detail?content_id16529801754907176021 SpringBoot多环境docker集成企业微信会话存档sdk 对于现在基本流行的springboot环境&#xff0c;官方文档真是比…

DAY64||dijkstra(堆优化版)精讲 ||Bellman_ford 算法精讲

dijkstra&#xff08;堆优化版&#xff09;精讲 题目如上题47. 参加科学大会&#xff08;第六期模拟笔试&#xff09; 邻接表 本题使用邻接表解决问题。 邻接表的优点&#xff1a; 对于稀疏图的存储&#xff0c;只需要存储边&#xff0c;空间利用率高遍历节点链接情况相对容…

在openi平台 基于华为顶级深度计算平台 openmind 动手实践

大家可能一直疑问&#xff0c;到底大模型在哪里有用。 本人从事的大模型有几个方向的业务。 基于生成式语言模型的海事航行警告结构化解析。 基于生成式语言模型的航空航行警告结构化解析。 基于生成式生物序列&#xff08;蛋白质、有机物、rna、dna、mrna&#xff09;的多模态…

Figma汉化:提升设计效率,降低沟通成本

在UI设计领域&#xff0c;Figma因其强大的功能而广受欢迎&#xff0c;但全英文界面对于国内设计师来说是一个不小的挑战。幸运的是&#xff0c;通过Figma汉化插件&#xff0c;我们可以克服语言障碍。以下是两种获取和安装Figma汉化插件的方法&#xff0c;旨在帮助国内的UI设计师…

深度学习-卷积神经网络CNN

案例-图像分类 网络结构: 卷积BN激活池化 数据集介绍 CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像&#xff0c;图像大小32323。下图列举了10个类&#xff0c;每一类随机展示了10张图片&#xff1a; 特征图计算 在卷积层和池化层结束后, 将特征…

关于adb shell登录开发板后terminal显示不完整

现象 今天有个同事跟我说&#xff0c;adb shell 登录开发板后&#xff0c;终端显示不完整&#xff0c;超出边界后就会出现奇怪的问题&#xff0c;比如字符覆盖显示等。如下图所示。 正常情况下应该如下图所示&#xff1a; 很明显&#xff0c;第一张图的显示区域只有完整区域…

【论文分享】三维景观格局如何影响城市居民的情绪

城市景观对居民情绪的影响是近些年来讨论的热门话题之一&#xff0c;现有的研究主要以遥感影像为数据来源&#xff0c;进行二维图像-数据分析&#xff0c;其量化结果精确度有限。本文引入了三维景观格局的研究模型&#xff0c;通过街景图片及网络发帖信息补充图像及数据来源&am…

ChatGPT学术专用版,一键润色纠错+中英互译+批量翻译PDF

ChatGPT academic项目是由中科院团队基于ChatGPT专属定制。论文润色、语法检查、中英互译、代码解释等可一键搞定&#xff0c;堪称科研神器。 功能介绍 我们以3.5版本为例&#xff0c;ChatGPT学术版总共分为五个区域&#xff1a;输入控制区、输出对话区、基础功能区、函数插件…

Go 语言已立足主流,编程语言排行榜24 年 11 月

Go语言概述 Go语言&#xff0c;简称Golang&#xff0c;是由Google的Robert Griesemer、Rob Pike和Ken Thompson在2007年设计&#xff0c;并于2009年11月正式宣布推出的静态类型、编译型开源编程语言。Go语言以其提高编程效率、软件构建速度和运行时性能的设计目标&#xff0c;…