DAY36:贪心算法(三)最大子数组和+买卖股票最佳时机

文章目录

    • 53.最大子数组和
      • 枚举思路
      • 暴力解法
      • 贪心思路
      • 完整版
      • 时间复杂度
    • 122.买卖股票的最佳时机Ⅱ(解法比较巧妙)
      • 思路
      • 完整版
      • 总结

53.最大子数组和

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

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6

示例 2:

输入:nums = [1]
输出:1

示例 3:

输入:nums = [5,4,-1,7,8]
输出:23

提示:

  • 1 <= nums.length <= 10^5
  • -10^4 <= nums[i] <= 10^4

枚举思路

本题的暴力解法就是两个for循环,一个for循环遍历子数组,一个for循环用来计算当前数值对应的所有子数组的和枚举所有的和,最后返回最大值。

暴力解法

class Solution {
public:int maxSubArray(vector<int>& nums) {int result = INT_MIN;int sum=0;for(int i=0;i<nums.size();i++){//求所有以i为开头的子数组的和for(int j=i;j<nums.size();j++){sum += nums[j];result = result>sum?result:sum;}//遍历完一个数字之后重置sumsum=0;}return result;}
};

暴力解法逻辑比较简单,但是超时了

在这里插入图片描述

贪心思路

因为这个题目数组里面有负数,负数累加只会让值变得更小。因此,与其使用-2,不如重新开始,以新的位置作为连续和的起点

局部最优就是,当求解连续和为负数的时候,立刻抛弃,因为负数只会影响总和。全局最优就是找到最大子数组的和。

注意,只是连续和是负数的时候就抛弃,不是遇到负数就抛弃!因为示例可以看到,很有可能最后的结果,本来就是带有负数的

只要连续和不是负数,就往后加,因为正数对后面的数一定有增大作用。result会记录到目前为止的最大值,因此不需要担心前面的正数或者较大的总和被漏掉的情况

贪心策略如下图所示。只要连续和是负数,负数一定没有正面作用,就立刻抛弃,选择下一个位置为起点

在这里插入图片描述

完整版

  • 注意舍弃负数的情况,不需要改变for循环起始位置只需要sum置零,就算是重新开始计数了
  • 题目没有说如果数组为空,应该返回什么,所以数组为空的话返回什么都可以
class Solution {
public:int maxSubArray(vector<int>& nums) {int result=INT_MIN;int sum=0;for(int i=0;i<nums.size();i++){sum+=nums[i];//先给result赋值,收集所有最大值防止全是负数result = result>sum?result:sum;//如果遇到负数if(sum<0){//如果<0,不需要改变for循环起始位置,直接sum赋值成0,就是从下一个重新开始计数!sum=0;}}return result;}
};

时间复杂度

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

122.买卖股票的最佳时机Ⅱ(解法比较巧妙)

  • 本题解法很巧妙,接触过之后要记住这种解法,即隔几天售卖的总利润每天利润累加实质上是相等的!

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

示例 1:

输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。总利润为 4 + 3 = 7

示例 2:

输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。总利润为 4

示例 3:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0

提示:

  • 1 <= prices.length <= 3 * 10^4
  • 0 <= prices[i] <= 10^4

思路

本题为什么会考虑用贪心来做,就是因为任意两天的利润差值,都可以进行拆分,拆成每相邻两天利润差值的和

示例如下图所示:

在这里插入图片描述
此时,拆成了相邻两天的差值,思路就和上一道题比较类似了。

如果想要总利润变大,遇到利润为负数的时候需要立刻舍弃,然后在下一个新起点开始重新计数。我们只尝试收集正的利润。示意图如下:

在这里插入图片描述
本题的情况,任何时候只能持有一支,但是可以多次买卖,也就是说只要在所有相邻元素后-前的结果中,全部收获正数,就可以获取最大收益。

贪心策略局部最优就是遇到正数就收集,全局最优就是结果最大

完整版

class Solution {
public:int maxProfit(vector<int>& prices) {int result=0;int count=0;for(int i=0;i<prices.size()-1;i++){count = prices[i+1]-prices[i];if(count>0){result+=count;}}return result;}
};

总结

这道题用的是一种非常巧妙的思路,把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑。把问题转换成相邻数字的差累加最大值的问题,就很好写了。

本题中理解利润拆分是关键点! 不要整块的去看,而是把整体利润拆为每天的利润

因为1–3天整体的利润1–3天每天的利润累加,在数学上就是一个恒等式

贪心的问题就是没接触过会很难想到,接触过之后,下次遇到这种情形,就可以考虑这样的解法了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文解读:PeSTo:用于精确预测蛋白质结合界面的无参数几何深度学习

Title:PeSTo: parameter-free geometric deep learning for accurate prediction of protein binding interfaces 期刊&#xff1a;nature communication 分区&#xff1a;一区 影响因子&#xff1a;16.6 webserver:t Pesto Github:GitHub - LBM-EPFL/PeSTo 摘要 蛋白质是…

Spring Boot 中的 CompletableFuture 类是什么,如何使用?

Spring Boot 中的 CompletableFuture 类是什么&#xff0c;如何使用&#xff1f; 介绍 在开发企业级应用程序时&#xff0c;我们经常需要异步执行任务。异步执行任务可以提高应用程序的性能和响应能力。在 Java 8 中&#xff0c;引入了 CompletableFuture 类&#xff0c;它提…

git no matching host key type found. Their offer: ssh-rsa

本地生成ssh&#xff0c;并配置了服务器SSH Public Keys 问题 拉去远程代码报错 git no matching host key type found. Their offer: ssh-rsa (base) tangsiqitangsiqideMacBook-Pro VDI % git clone "ssh://tangsiqireview.archeros.cn:29418/ArcherDT/vdi-server&…

Centos 7 下安装Redis

官网地址&#xff08;英文&#xff09;&#xff1a;Redis 官网地址&#xff08;中文&#xff09;&#xff1a;CRUG网站 or redis中文文档 Redis源码地址&#xff1a;GitHub - redis/redis: Redis is an in-memory database that persists on disk. The data model is key-v…

500万PV的网站需要多少台服务器?

1. 衡量业务量的指标 衡量业务量的指标项有很多&#xff0c;比如&#xff0c;常见Web类应用中的PV、UV、IP。而比较贴近业务的指标项就是大家通常所说的业务用户数。但这个用户数比较笼统&#xff0c;其实和真实访问量有比较大的差距&#xff0c;所以为了更贴近实际业务量及压力…

非主流币波段策略

数量技术宅团队在CSDN学院推出了量化投资系列课程 欢迎有兴趣系统学习量化投资的同学&#xff0c;点击下方链接报名&#xff1a; 量化投资速成营&#xff08;入门课程&#xff09; Python股票量化投资 Python期货量化投资 Python数字货币量化投资 C语言CTP期货交易系统开…

五.LLC谐振变换器

LLC 谐振变换器启动过程分析 LLC 谐振变换器的组成结构中包含容性器件&#xff0c;为了尽可能减小输出电压纹波&#xff0c;钳位输出电压&#xff0c;此时希望输出滤波电容尽可能的大&#xff0c;因此也会在启动的时候&#xff0c;电容两端电压近似为 0&#xff0c;系统对电容…

Vue3.3 编译宏

Vue 3.3新增了一些语法糖和宏&#xff0c;包括泛型组件、defineSlots、defineEmits、defineOptions defineProps 父子组件传参 <template><div><Child name"xiaoman"></Child></div> </template><script langts setup>…

装饰器模式:通过剖析Java IO类库源码学习装饰器模式

我们通过剖析Java IO类的设计思想&#xff0c;再学习一种新的结构型模式&#xff0c;装饰器模式。它的代码结构跟桥接模式非常相似&#xff0c;不过&#xff0c;要解决的问题却大不相同。 Java IO类库非常庞大和复杂&#xff0c;有几十个类&#xff0c;负责IO数据的读取…

【高级程序设计语言C++】类与对象

2.1类的定义2.1.1 类的两种定义方式2.1.2 类的访问限定符2.1.3 C中的struct和class的区别是什么&#xff1f;2.1.4 类的实例化2.1.5 计算类对象的大小2.1.6 this指针 2.2 类的6个默认成员函数2.2.1 构造函数2.2.2 析构函数2.2.3 拷贝构造函数2.2.4 赋值运算符重载2.2.5 取地址及…

Linux 网络延迟排查方法详解

概要 在 Linux 服务器中&#xff0c;可以通过内核调优、DPDK 以及 XDP 等多种方式提高服务器的抗攻击能力&#xff0c;降低 DDoS 对正常服务的影响。在应用程序中&#xff0c;可以使用各级缓存、WAF、CDN 等来缓解 DDoS 对应用程序的影响。 但是需要注意的是&#xff0c;如果 …

液滴接触角边界曲线识别—巧用Ovito

关注 M r . m a t e r i a l , \color{Violet} \rm Mr.material\ , Mr.material , 更 \color{red}{更} 更 多 \color{blue}{多} 多 精 \color{orange}{精} 精 彩 \color{green}{彩} 彩&#xff01; 主要专栏内容包括&#xff1a; †《LAMMPS小技巧》&#xff1a; ‾ \textbf…