贪心法思想-求最大子数组和案例图解

news2024/10/6 22:31:56

贪心法思想

​ 基本思想是在问题的每个决策阶段,都选择当前看起来最优的选择,即贪心地做出局部最优的决策,以期获得全局最优解。

​ 正如其名字一样,贪心法在解决问题的策略上目光短浅,只根据当前已有的信息做出选择。一旦做出选择,不管将来有什么结果,这个选择都不会改变。

与动态规划对比:

​ 贪心算法和动态规划都常用于解决优化问题。它们之间存在一些相似之处,比如都依赖最优子结构性质,但工作原理不同。

  • 动态规划会根据之前阶段的所有决策来考虑当前决策,并使用过去子问题的解来构建当前子问题的解。
  • 贪心算法不会考虑过去的决策,而是一路向前地进行贪心选择,不断缩小问题范围,直至问题被解决。

举例-零钱兑换问题:

​ 贪心算法实现简单,易于理解,效率也很高,但是具有局限性。

有一组不同面额的硬币,给定一个总金额 𝑎𝑚𝑡 ,计算并返回可以凑成总金额所需的最少的硬币个数 。

每次贪心的选择尽可能大的硬币(不大于总金额的最大硬币),直至凑出目标金额为止。

硬币组合[100、50、10、5、1],总金额amt为131:

在这里插入图片描述

但是,某些情况下使用贪心是无法得到最优解的:

​ 硬币组合:[1,20,50],总金额 𝑎𝑚𝑡=60 ,贪心算法只能找到 50+1×10 的兑换组合,共计 11 枚硬币,但动态规划可以找到最优解 20+20+20 ,仅需 3 枚硬币。

分析:

​ 对于组合1、3、4,需要金额6,那么按照贪心法:4+1+1三个,而3+3两个即可。

​ 如果硬币组合间有倍数关系,那么较大的硬币可以使用多个较小的硬币组合,意味着能用较小硬币的任意数量组合(加起来大于较大硬币),都可以直接使用较大硬币+一定数量的较小硬币替代去减少数量,不会出现3+3等于6,而4和3无法组合出6的这种情况。

贪心法案例-求最大子数组和图解

问题描述:

​ 给一个整数数组 ,请找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

原始数组:

nums = [-2,1,-3,4,-1,2,1,-5,4]

蛮力法:

​ 直接遍历所有情况,将任意情况下的最优解记录下来,取最大的

 public static int solution(int[] data, int n) {
        if (n < 0 || (n == 1 && data[0] <= 0)) {
            return 0;
        }
        if (n == 1) {
            return data[0];
        }
        int maxSum = 0, thisSum;
        // 计算i到i,i到i+1,...,i到n的和,选出最大的一个子序列。  
        // 当i从0遍历到n-1时,则计算过了所有的子序列
        for (int i = 0; i < n; i++) {
            thisSum = 0;// i 表示子序列左侧的位置
            for (int j = i; j < n; j++) { // j 表示子序列右边的位置
                // 汇总 i到j 的所有数之和时,对比solution1发现
                // 其实每次求和不需要都从i位置开始,因为 i到k的和 = i到K-1的和 + data[k]
                thisSum += data[j];
                maxSum = Math.max(maxSum, thisSum);
            }
        }
        return maxSum;
    }
贪心法:

​ 如果当前的子序列和小于0,那么负数+任何数都会变小,所以应该舍弃掉当前已经选择的子序列。

​ 所以我们只需要考虑当前的最优解即可,不断向后遍历数组,直到遍历完数组就可以得到最大的子序列和。

1、初始化

在这里插入图片描述

2、下标0

​ 下标为0,此时当前最大值变为 0 + ( − 2 ) = − 2 0+(-2)=-2 0+(2)=2,然后结果取负无穷和-2之间较大的,即-2.

t h i s M a x S u b = 0 + ( − 2 ) = − 2 thisMaxSub = 0 + (-2) = -2 thisMaxSub=0+(2)=2

− 2 > 负无穷  推出   r e s u l t = − 2 -2>负无穷 ~~推出~~ result = -2 2>负无穷  推出  result=2

​ 因为-2为负数,一定会使后续的子序列和变小,直接舍弃。

− 2 < 0   推出   t h i s M a x S u b = 0 -2<0 ~~推出~~ thisMaxSub = 0 2<0  推出  thisMaxSub=0

在这里插入图片描述

3、下标1

​ 当前最大值变为 0 + 1 = 1 0+1=1 0+1=1,然后结果取-2和1之间较大的,即1.

t h i s M a x S u b = 0 + 1 = 1 thisMaxSub = 0 +1= 1 thisMaxSub=0+1=1

1 > − 2   推出   r e s u l t = 1 1>-2 ~~推出~~ result = 1 1>2  推出  result=1

在这里插入图片描述

3、下标2

​ 当前最大值变为 1 + ( − 3 ) = − 2 1+(-3)=-2 1+(3)=2,然后结果取1和-2之间较大的,即1.

t h i s M a x S u b = 1 + ( − 3 ) = − 2 thisMaxSub = 1 + (-3) = -2 thisMaxSub=1+(3)=2

1 > − 2   推出   r e s u l t = 1 1>-2 ~~推出~~ result = 1 1>2  推出  result=1

​ 因为-2为负数,一定会使后续的子序列和变小,直接舍弃。

− 2 < 0   推出   t h i s M a x S u b = 0 -2<0 ~~推出~~ thisMaxSub = 0 2<0  推出  thisMaxSub=0

在这里插入图片描述

4、下标3

​ 当前最大值变为 0 + 4 = 4 0+4=4 0+4=4,然后结果取1和4之间较大的,即4.

t h i s M a x S u b = 0 + 4 = 4 thisMaxSub = 0 + 4 = 4 thisMaxSub=0+4=4

4 > 1   推出   r e s u l t = 4 4>1 ~~推出~~ result = 4 4>1  推出  result=4

在这里插入图片描述

5、下标4

​ 当前最大值变为 4 + ( − 1 ) = 3 4+(-1)=3 4+1=3,然后结果取4和3之间较大的,即4.

t h i s M a x S u b = 4 + ( − 1 ) = 3 thisMaxSub = 4 + (-1) = 3 thisMaxSub=4+1=3

4 > 3   推出   r e s u l t = 4 4>3 ~~推出~~ result = 4 4>3  推出  result=4

在这里插入图片描述

6、下标5

​ 当前最大值变为 3 + 2 = 5 3+2=5 3+2=5,然后结果取4和5之间较大的,即5.

t h i s M a x S u b = 3 + 2 = 5 thisMaxSub = 3+2=5 thisMaxSub=3+2=5

5 > 4   推出   r e s u l t = 5 5>4 ~~推出~~ result = 5 5>4  推出  result=5

在这里插入图片描述

​ 最终得到最大值为6

    public static int execute(int[] data) {
        // result:存储最大值;thisMaxSub:存储当前最大值
        int result = Integer.MIN_VALUE, thisMaxSub = 0;
        for (int datum : data) {
            thisMaxSub += datum;
            result = Math.max(thisMaxSub, result);
            // tempMaxSub小于0的话,就可以直接舍弃掉,因为负数+任何数都会变得更小
            thisMaxSub = Math.max(thisMaxSub, 0);
        }
        return result;
    }

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

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

相关文章

【FFmpeg】avformat_write_header函数

FFmpeg相关记录&#xff1a; 示例工程&#xff1a; 【FFmpeg】调用ffmpeg库实现264软编 【FFmpeg】调用ffmpeg库实现264软解 【FFmpeg】调用ffmpeg库进行RTMP推流和拉流 【FFmpeg】调用ffmpeg库进行SDL2解码后渲染 流程分析&#xff1a; 【FFmpeg】编码链路上主要函数的简单分…

VMware中安装CentOS系统

VMware中安装CentOS系统 CentOS 镜像的准备创建虚拟机Cent OS系统的安装 CentOS 镜像的准备 下载链接&#xff1a;清华园CenOS 7镜像下载 VMware的安装参考&#xff1a;VMware workstation pro 16 虚拟机的安装 创建虚拟机 1.打开VMware workstation pro 16->创建新的虚拟…

[leetcode]insert-into-a-binary-search-tree

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:TreeNode* insertIntoBST(TreeNode* root, int val) {if (root nullptr) {return new TreeNode(val);}TreeNode* pos root;while (pos ! nullptr) {if (val < pos->val) {if (pos->left nullptr…

掌握Python编程的深层技能

一、Python基础语法、变量、列表、字典等运用 1.运行python程序的两种方式 1.交互式即时得到程序的运行结果 2.脚本方式把程序写到文件里(约定俗称文件名后缀为.py),然后用python解释器解释执行其中的内容2.python程序运行的三个步骤 python3.8 C:\a\b\c.py 1.先启动python3…

揭秘循环购模式:消费即赚钱,私域电商新纪元

消费1000送2000、每天领钱、钱还可以提现&#xff0c;这样的商业模式——循环购模式&#xff0c;确实在私域电商领域引起了广泛的关注。这种模式的成功并非偶然&#xff0c;而是基于合理的返利规则和商业模式创新。下面我将为您详细解析循环购模式为何能够吸引消费者&#xff0…

记录一次——RK100键盘按键失效修复

一、背景说明: 背景&#xff1a;购买的键盘是RK的型号RK100&#xff0c;具有紧凑的外观&#xff0c;并搭配了TTC金粉轴&#xff0c;使用起来还不错&#xff0c;目前已经是第3年了。问题&#xff1a;前几个月会出现H按键失效的问题&#xff0c;但是过一段时间又会修复。最近是Q…

深入解析链表:解锁数据结构核心奥秘

一. 链表的定义 链表是一种线性数据结构&#xff0c;由一系列节点组成。每个节点包含两个部分&#xff1a; 数据域&#xff08;Data&#xff09;&#xff1a;存储节点的数据。指针域&#xff08;Pointer&#xff09;&#xff1a;存储指向下一个节点的地址。 链表的第一个节点…

一招教你用python代码给朋友写一个爱心代码

有人问我马上要跟女朋友一周年了&#xff0c;能不能用代码给他写一个爱心代码呢&#xff1f;那算你问对人了&#xff0c;来上才艺 可以使用Python的turtle模块来绘制一个爱心形状。下面是一个简单的示例代码&#xff0c;我将详细解释每一步&#xff1a; import turtle # 创建一…

制定班规要注意哪些事项

对于如何管理班级&#xff0c;制定班规是一项至关重要的任务。关系到班级的日常秩序&#xff0c;影响着学生的集体荣誉感。制定班规并非易事&#xff0c;需要深思熟虑和周全考虑。 班规的制定应以学生为中心。深入了解学生的需求和期望&#xff0c;以及他们在学习和生活中可能遇…

统计信号处理基础 习题解答11-6

题目 考虑例11.1对WGN中单个正弦信号的数据模型&#xff0c;将模型重写为 其中&#xff1a; &#xff0c;证明A的PDF是瑞丽的&#xff0c;的PDF是&#xff0c;且和是相互独立的。 解答 根据例11.1&#xff1a; 由于N维联合高斯分布为&#xff1a; 由&#xff1a; 因此&#…

Java程序员学习Go开发Higress的WASM插件

Java程序员学习Go开发Higress的WASM插件 契机 ⚙ 今年天池大赛有higress相关挑战&#xff0c;研究一下。之前没搞过go&#xff0c;踩了很多坑&#xff0c;最主要的就是tinygo打包&#xff0c;多方寻求解决无果&#xff0c;结论是tinygo0.32go1.19无法在macos arm架构下打包。…

一键掌控,文件格式转换无忧!轻松驾驭各种文件格式,高效管理您的数字世界

信息爆炸的时代&#xff0c;我们每天都会接触到各种各样的文件格式。无论是工作文档、图片、视频还是音频文件&#xff0c;它们都以不同的格式存在于我们的电脑和移动设备中。然而&#xff0c;不同的软件和应用往往只支持特定的文件格式&#xff0c;这给我们的工作和生活带来了…

Petal-X :心血管疾病临床风险可视化工具

心血管疾病&#xff08;Cardiovascular diseases, CVDs&#xff09;是全球致死的首要原因&#xff0c;但在大多数情况下&#xff0c;它们是可以通过行为干预来预防的。因此&#xff0c;在个体层面上&#xff0c;有效地传达心血管疾病的风险以及通过风险因素的修改来预计风险降低…

无线WiFi毫米波雷达传感器成品,智能照明人体感应开关,飞睿智能点亮智慧生活

在智能科技飞速发展的今天&#xff0c;我们的生活正被各种智能设备所包围&#xff0c;其中智能照明作为智能家居的重要组成部分&#xff0c;正逐渐改变着我们的生活方式。而在这背后&#xff0c;有一个默默工作的“小助手”——飞睿智能毫米波雷达传感器&#xff0c;它就像智能…

周边美食小程序系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;美食店铺管理&#xff0c;菜品分类管理&#xff0c;标签管理&#xff0c;菜品信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;美食店铺&#…

网页用事件监听器播放声音

一、什么是监听器&#xff1a; 在前端页面中&#xff0c;事件监听器&#xff08;Event Listener&#xff09;是一种编程机制&#xff0c;它允许开发者指定当特定事件&#xff08;如用户点击按钮、鼠标悬停、页面加载完成等&#xff09;发生时执行特定的代码块。简而言之&#x…

css 滚动词云

css javascript 实现滚动词云效果 // 163css.js var radius 120; var dtr Math.PI / 180; var d 300; var mcList []; var active false; var lasta 1; var lastb 1; var distr true; var tspeed 10; var size 250; var mouseX 0; var mouseY 0; var howElliptic…

使用面向对象方式编写ROS2节点

1.使用c方式创建节点 在d2lros2/chapt2/chapt2_ws/src/example_cpp/src下新建node_03.cpp&#xff0c;接着输入下面的代码。 #include "rclcpp/rclcpp.hpp" /* 创建一个类节点&#xff0c;名字叫做Node03,继承自Node. */ class Node03 : public rclcpp::Node {…

数据脱敏学习

数据脱敏是一种保护敏感信息的方法&#xff0c;它通过修改或删除数据中的敏感部分&#xff0c;使得数据在保持一定可用性的同时&#xff0c;不再直接关联到个人隐私或重要信息。 自然人指可以直接或间接标识 直接标识&#xff1a;如姓名、身份证号码、家庭住址、电话号码、电…

权威认可 | Smartbi连续5年入选“Gartner增强数据分析代表厂商”

近日&#xff0c;全球权威技术研究与咨询公司Gartner最新发布《2024 年中国数据、分析和人工智能技术成熟度曲线》&#xff0c;Smartbi以其卓越的增强数据分析及自助分析能力&#xff0c;再次入选代表厂商&#xff0c;这也是Smartbi连续5年入选增强数据分析及自助分析代表厂商&…