LeetCode 122. 买卖股票的最佳时机 II(中等)

基于STM32控制直流电机加减速正反转仿真设计 *单片机设计介绍,基于STM32控制直流电机加减速正反转仿真设计。 阅读详情

题目描述

给你一个整数数组 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

 问题分析

与"买卖股票的最佳时机 I"不同,这道题允许我们进行多次交易,但有以下限制:

  1. 在任何时候最多只能持有一股股票
  2. 必须先买入才能卖出(不能卖空)
  3. 可以在同一天买入并卖出

关键问题是:如何安排买入和卖出的时机,使得总利润最大?


解题思路

贪心算法

这道题有一个非常直观的贪心解法。由于可以进行无限次交易,我们可以采取"只要有利可图就交易"的策略。具体来说:

  1. 当股票价格上涨时(明天价格 > 今天价格),我们应该在今天买入,明天卖出,赚取差价
  1. 当股票价格下跌时,我们不进行任何操作

这个策略可以进一步简化:只需要将所有相邻两天的价格上涨都累加起来,就得到了最大利润。

例如,对于数组 [1,2,3,4,5]:

  • 第1天买入,第5天卖出,利润是 5-1=4
  • 等价于:(2-1)+(3-2)+(4-3)+(5-4)=4

即将所有上涨的部分都累加起来,就是最大利润。

为什么贪心算法有效?

假设我们有三天的价格:a, b, c,其中 a < b > c(即价格先上涨后下跌)。

如果我们在价格为a时买入,在价格为b时卖出,然后在价格为c时再买入,总利润为(b-a)。

如果我们选择持有(即在价格为a时买入,一直持有到价格为c),利润为(c-a),由于c<b,所以(c-a)<(b-a),不如前一种策略获利多。

代码实现

Java 实现

class Solution {
    public int maxProfit(int[] prices) {
        // 边界条件检查
        if (prices == null || prices.length <= 1) {
            return 0;
        }
        
        int totalProfit = 0;
        
        // 遍历价格数组
        for (int i = 1; i < prices.length; i++) {
            // 如果当前价格高于前一天的价格,就进行交易
            if (prices[i] > prices[i - 1]) {
                // 累加这一天的利润
                totalProfit += prices[i] - prices[i - 1];
            }
        }
        
        return totalProfit;
    }
}

我们还可以添加一些调试信息,以便更清楚地理解算法的执行过程:

class Solution {
    public int maxProfit(int[] prices) {
        if (prices == null || prices.length <= 1) {
            return 0;
        }
        
        int totalProfit = 0;
        System.out.println("初始总利润: " + totalProfit);
        
        for (int i = 1; i < prices.length; i++) {
            int todayPrice = prices[i];
            int yesterdayPrice = prices[i - 1];
            
            if (todayPrice > yesterdayPrice) {
                int profit = todayPrice - yesterdayPrice;
                totalProfit += profit;
                System.out.println("第" + i + "天: 价格从 " + yesterdayPrice + 
                                  " 上涨到 " + todayPrice + ", 获利 " + profit + 
                                  ", 总利润增加到 " + totalProfit);
            } else {
                System.out.println("第" + i + "天: 价格从 " + yesterdayPrice + 
                                  " 下跌到 " + todayPrice + ", 不操作, 总利润仍为 " + 
                                  totalProfit);
            }
        }
        
        return totalProfit;
    }
}

输入:prices = [7,1,5,3,6,4]

初始总利润: 0
第1天: 价格从 7 下跌到 1, 不操作, 总利润仍为 0
第2天: 价格从 1 上涨到 5, 获利 4, 总利润增加到 4
第3天: 价格从 5 下跌到 3, 不操作, 总利润仍为 4
第4天: 价格从 3 上涨到 6, 获利 3, 总利润增加到 7
第5天: 价格从 6 下跌到 4, 不操作, 总利润仍为 7

C# 实现

public class Solution {
    public int MaxProfit(int[] prices) {
        // 边界条件检查
        if (prices == null || prices.Length <= 1) {
            return 0;
        }
        
        int totalProfit = 0;
        
        // 遍历价格数组
        for (int i = 1; i < prices.Length; i++) {
            // 如果当前价格高于前一天的价格,就进行交易
            if (prices[i] > prices[i - 1]) {
                // 累加这一天的利润
                totalProfit += prices[i] - prices[i - 1];
            }
        }
        
        return totalProfit;
    }
}

详细执行过程图解

以示例 [7,1,5,3,6,4] 为例,让我们详细跟踪算法的执行过程:

初始总利润:0

第1天 → 第2天:价格从 7 下跌到 1,不操作,总利润仍为 0

第2天 → 第3天:价格从 1 上涨到 5,进行交易:

  • 第2天买入(价格=1)
  • 第3天卖出(价格=5)
  • 获利:5-1=4
  • 总利润:0+4=4

第3天 → 第4天:价格从 5 下跌到 3,不操作,总利润仍为 4

第4天 → 第5天:价格从 3 上涨到 6,进行交易:

  • 第4天买入(价格=3)
  • 第5天卖出(价格=6)
  • 获利:6-3=3
  • 总利润:4+3=7

第5天 → 第6天:价格从 6 下跌到 4,不操作,总利润仍为 7

最终总利润:7

价格-时间图解

股票价格变化图:

 价格
  ^
7 | *
6 |             *
5 |       *       
4 |                *
3 |          *   
2 |            
1 |    *       
0 +-------------------> 时间
    1  2  3  4  5  6

交易策略图解:

 价格
  ^
7 |*
6 |            *卖出
5 |       *卖出   
4 |               *
3 |          *买入
2 |            
1 |    *买入    
0 +-----------------> 时间
    1  2  3  4  5  6

算法分析

贪心算法的正确性

为什么这个贪心策略是正确的?我们可以证明,对于任何一段连续上涨的区间[i, j],在i买入,在j卖出的利润等于区间内所有相邻两天价格差的总和:

prices[j] - prices[i] = (prices[i+1] - prices[i]) + (prices[i+2] - prices[i+1]) + ... + (prices[j] - prices[j-1])

因此,无论是选择在整个上涨区间买卖一次,还是每天都进行买卖,最终的利润是相同的。而对于下跌区间,不进行操作是最优的。

复杂度分析

  • 时间复杂度:O(n),其中 n 是价格数组的长度。我们只需要遍历一次数组。
  • 空间复杂度:O(1),只使用了常数额外空间。

动态规划解法

虽然贪心算法已经能够解决这个问题,但我们也可以使用动态规划的思路来解决。这种方法对于理解更复杂的股票问题很有帮助。

定义状态:

  • dp[i][0]:第i天交易结束后不持有股票的最大利润
  • dp[i][1]:第i天交易结束后持有股票的最大利润

状态转移方程:

  • dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])(今天不持有 = max(昨天不持有,昨天持有今天卖出))
  • dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])(今天持有 = max(昨天持有,昨天不持有今天买入))

初始状态:

  • dp[0][0] = 0(第0天不持有股票,利润为0)
  • dp[0][1] = -prices[0](第0天持有股票,利润为-prices[0])

最终答案是 dp[n-1][0],即最后一天不持有股票的最大利润。

Java实现:

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (n <= 1) return 0;
        
        int[][] dp = new int[n][2];
        
        // 初始状态
        dp[0][0] = 0;            // 第0天不持有股票
        dp[0][1] = -prices[0];   // 第0天持有股票
        
        // 状态转移
        for (int i = 1; i < n; i++) {
            // 今天不持有 = max(昨天不持有,昨天持有今天卖出)
            dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]); 
            // 今天持有 = max(昨天持有,昨天不持有今天买入)
            dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
        }
        
        return dp[n-1][0];  // 最后一天不持有股票的最大利润
    }
}

空间优化的动态规划(因为只依赖前一天的状态):

class Solution {
    public int maxProfit(int[] prices) {
        int n = prices.length;
        if (n <= 1) return 0;
        
        int noStock = 0;           // 不持有股票的最大利润
        int hasStock = -prices[0]; // 持有股票的最大利润
        
        for (int i = 1; i < n; i++) {
            int prevNoStock = noStock;
            // 今天不持有 = max(昨天不持有,昨天持有今天卖出)
            noStock = Math.max(noStock, hasStock + prices[i]);
            // 今天持有 = max(昨天持有,昨天不持有今天买入)
            hasStock = Math.max(hasStock, prevNoStock - prices[i]);
        }
         
        return noStock;
    }
}

总结

买卖股票的最佳时机 II 是一个经典的贪心算法问题。通过简单的策略——只要价格上涨就进行交易,我们就能获得最大的利润。

这个问题的关键洞察是:

  1. 由于可以进行无限次交易,我们可以将任何一段上涨区间的总利润分解为每日差价之和
  2. 对于下跌区间,不进行操作是最优的

与第一题(只能交易一次)相比,这个问题实际上更简单,因为我们不再需要寻找全局最优的买入卖出点,而是可以采取局部贪心的策略。

理解这个问题对于解决更复杂的股票交易问题(如限制交易次数、有冷却期、有交易费用等)也很有帮助。

从零开始:用ADS 2023手把手教你设计2.4GHz Wi-Fi LNA(基于ATF-54143,附模型文件) 本文详细介绍了如何使用ADS 2023软件设计2.4GHz Wi-Fi频段的低噪声放大器(LNA),基于ATF-54143晶体管。内容涵盖模型导入、直流工作点确定、稳定性优化、噪声匹配等关键步骤,并提供可下载的模型文件包,帮助工程师快速掌握LNA设计技巧。 阅读详情

相关推荐

手把手实战:快速构建合同智能审查Agent

配置“模型供应商”,选择 “OpenAI-API-compatible”,输入申请到的 “API Key” 和 “URL” 后点击“保存”,如下图示例完成 “AlayaNew/DeepSeek-R1。至此,我们完成了合同智能审核Agent的构建,我们也可以在Dify中把这个智能体发布为API服务,这样企业其它应用如OA就可以通过API集成,在原合同流程中实现智能审核工作。该节点“输入变量”中,配置从“开始”节点中获取上传的文件,输出变量就是合同的内容,配置如下图。接下来我们开始创建智能体。

weixin_46880696的博客 4403

leetcode每日一题——122.买卖股票的最佳时机II(面试经典150题)

leetcode每日一题——122.买卖股票的最佳时机II(面试经典150题) 内容主要包括对这一题目的思路分析、步骤分析以及代码实现

m0_59800431的博客 1474

从一个过气考渣的角度看LLM智能化测试用例生成

根据业务需求生成测试用例,会涉及到相关上下文的召回、用例生成等场景。除了用例生成之外,也可以考虑应用LLM进行用例评审。因此,本文将涉及以下内容。

software_test010的博客 827

leetcode:122. 买卖股票的最佳时机 II(买卖无限次)

121题中股票全程只能买卖一次,所以如果买入股票, 那么第i天持有股票即have[i]一定就是 -prices[i], 而本题中, 因为一只股票可以买卖多次, 所以当第i天买入股票的时候, 所持有的现金可能有之前买卖过的利润, 所以have[i]=no[i-1]-prices[i]. 这就是两题唯一不同的地方了, 其他地方都是一模一样了!因为本题的动态规划方法和[121. 买卖股票的最佳时机]只有一处不同, 其他的思路和代码是一模一样。即可, 就是最终答案.

OceanStar的博客 1501

AWD线下攻防赛总结

在本地组策略编辑器里面,依次展开计算机配置—>管理模板—>Windows组件—>远程桌面服务—>远程桌面会话主机—>连接—>限制连接的数量。8.Web目录环境查找相关可疑文件:jpg/png/rar,属性、解压。进程线程:netstat / ps -aux/netstat -apt。4.查看/etc/init.d/rc.local中启动服务有无异常。1.不使用默认口令,修改成复杂的,并确保和web环境连接。5.使用脚本开启进程监控、目录监控、流量监控。文件操作监控.exe/御剑文件监控.exe。

XuJL89的博客 630

破解拼多多网页字体加密的Python实现(静态)

爬取或者复制粘贴出来发现数字不是6372,而是这样的一个东西 ""从上图我们可以看出数字是一行的空白,后面被浏览器渲染后才展现的数字。我们可以用这个代码查看十六位进制对应的十进制,为什么要看十进制呢?​,而字体文件中的字符映射关系(cmap)也是以十进制存储的。我们搜索这个属性我们可以看到第一个这样的属性有一个URL,这个就是解密的字体包。然后我们构造一个这样的映射字典 key就是对应的十进制,后面的值就是对应的数字。然后我们需要封装一个函数,将加密文字和映射字典传入,返回解密后的数字。

weixin_64179111的博客 3538

《LeetCode》—— 买卖股票的最佳时机

动态规划题目的讲解

m0_56069910的博客 3550

GLM-5.2模型自部署实战:如何通过量化与vLLM优化实现远超官方API的推理速度

在大模型应用开发中,模型推理速度是影响用户体验和系统性能的核心指标。其原理在于通过优化计算图、内存管理和并行计算来提升吞吐量与降低延迟。技术价值体现在能够为高并发、低延迟的实时应用提供稳定高效的AI服务能力,广泛应用于智能客服、代码生成、内容创作等场景。其中,模型量化通过降低权重精度(如INT4/INT8)来大幅减少显存占用和计算量,而推理引擎(如vLLM)则通过连续批处理和PagedAttention等技术最大化硬件利用率。本文聚焦于GLM-5.2模型,详细阐述如何通过量化技术与vLLM推理引擎的深度优化

weixin_29032337的博客 319

【力扣经典面试题】122. 买卖股票的最佳时机 II

初始化最大利润ans为0,获取股票价格数组的长度n。使用循环从第二天开始遍历到最后一天,对每一天进行处理。计算当前交易的利润,使用来保证利润不为负数,即如果价格上涨则累加利润,否则不进行操作。将每次计算得到的利润累加到总利润ans中。返回最终的总利润作为最大利润。该算法的核心思想是通过贪心策略,在每一次价格上涨时进行交易,以获得最大的累积利润。这样的贪心策略适用于该问题,因为我们只关心总体利润的增加,而不需要具体的买卖操作。最终的时间复杂度是O(n),其中n是股票价格数组的长度。

a910247的博客 742

Mathtype公式下标深度调整技巧:解决固定行距下的显示不全问题

本文针对在Word等文档中设置固定行距时,Mathtype公式下标显示不全的问题,提供了专业解决方案。核心在于调整Mathtype软件内部的“下标深度”参数,通过修改单个公式或批量格式化全文,使公式完美适配固定行距,确保下标清晰完整,且不影响文档整体排版。

pepsi的博客 1497

OWASP-ZAP扫描器的使用

目录 OWASP-ZAP 更新 代理 目录扫描 主动扫描(Active Scan) 扫描结果 生成报告 OWASP-ZAP OWASP Zed攻击代理(ZAP)是世界上最受欢迎的免费安全审计工具之一,由数百名国际志愿者积极维护。它可以帮助你在开发和测试应用程序时自动查找Web应用程序中的安全漏洞。 也可以说ZAP是一个中间人代理。它能够获取你对Web应用程序发出的所有请求以...

谢公子的博客 2万+

买卖股票的最佳时机II(数组)

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和或出售股票。你在任何时候只能持有股票。你也可以先购买,然后在出售。返回你能获得的利润。7在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。

creazypeople的博客 490

29、网络支持技术:CDN、覆盖网络与无标度网络解析

本文详细解析了CDN路由方式与性能指标,探讨了覆盖网络与无标度网络的特性及其在云计算和现代网络中的应用。文章分析了CDN的关键技术与挑战,介绍了覆盖网络与小世界网络的基本原理,并深入讨论了无标度网络的构建算法、性能优化策略以及在多个领域的应用案例。最后,文章展望了未来网络技术发展趋势与无标度网络的结合潜力。

night的博客 87

Leetcode—122.买卖股票的最佳时机II【中等】

运行结果 之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

Atticus的博客 186

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

00买股票最佳时机中等 LeetCode122. 买卖股票的最佳时机 II

122. 买卖股票的最佳时机 II 描述 给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 分析 第i天只有两种状态,不持有或持有股票,当天不持有股票的状态可能来自昨天卖出或者昨天也不持有,同理,当天持有股票的状态可能来自昨天买入或者昨天也持有中,取最后一天的不持有股票状态就是问题的解。 dp[i][0

31楼下小黑的博客 164

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

LeetCode-122买卖股票的最佳时机II-中等

122买卖股票的最佳时机II-中等

wxy 186

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【贪心算法】Leetcode 122. 买卖股票的最佳时机 II【中等】

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天。:在第 2 天(股票价格 = 1)的时候买入,在第 3 天。总利润为 4 + 3 = 7。这是一个典型的贪心算法问题。

FLGB 502

LeetCode_动态规划_中等_122.买卖股票的最佳时机 II

给定一个数组 prices,其中 prices[i] 是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

代码星辰的博客 410

Leetcode|中等|股票|122. 买卖股票的最佳时机 II

1 贪心算法 class Solution { public: int maxProfit(vector<int>& prices) { int curDiff = 0; int money = 0; for (int i = 0; i < prices.size(); i++) { if (i == 0) continue; curDiff = prices[i] - pr.

SL_World的博客 199

【LeetCode】122. 买卖股票的最佳时机 II(中等)——代码随想录算法训练营Day48

【LeetCode】122. 买卖股票的最佳时机 II

晴雪月乔的博客 884

【LeetCode】122. 买卖股票的最佳时机 II(中等)——代码随想录算法训练营Day32

【LeetCode】122. 买卖股票的最佳时机 II

晴雪月乔的博客 439

122. 买卖股票的最佳时机 II(中等)- LeetCode

题目描述 自己解法 采取的方法是计算折线图的每个上升区段,将峰值与低谷值相减得到每个上升区段的利润,最后进行累加,类似于官方题解中的第二种解法。时间复杂度O(n)O(n)O(n),空间复杂度O(1)O(1)O(1)。 class Solution: def maxProfit(self, prices: List[int]) -> int: ans = 0 start,end = 0,1 length = len(prices)

不学无术的小镇做题家 197

LeetCode(8)122. 买卖股票的最佳时机 II【数组/字符串】【中等】

LeetCode(8)122. 买卖股票的最佳时机 II【数组/字符串】【中等】

ACGkaka的博客 145

力扣记录:贪心算法2中等(2)股票问题——122 买卖股票的最佳时机II,714 买卖股票的最佳时机含手续费

力扣记录:贪心算法2中等(2)股票问题——122 买卖股票的最佳时机II,714 买卖股票的最佳时机含手续费

Kiwi_fruit的博客 323

LeetCode 面试经典 150_数组/字符串_买卖股票的最佳时机 II(8_122_C++_中等)(贪心算法)

LeetCode 面试经典 150_数组/字符串_买卖股票的最佳时机 II(8_122_C++_中等) 题目描述: 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。 在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。 返回 你能获得的 最大 利润 。

huayimenghan的博客 877

Day23 | 455. 分发饼干、376. 摆动序列、53. 最大子数组和、122. 买卖股票的最佳时机 II、55. 跳跃游戏、45. 跳跃游戏 II

122. 买卖股票的最佳时机 II。45. 跳跃游戏 II。53. 最大子数组和。

m0_56545264的博客 178
上一篇: 什么是Unity中的GameObject?
下一篇: Unity的FixedUpdate方法详解
枫景Maple
博客等级 码龄2年 485粉丝 100原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值