Day:动态规划 LeedCode 123.买卖股票的最佳时机III 188.买卖股票的最佳时机IV

news2024/12/23 16:14:36

123. 买卖股票的最佳时机 III

给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

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

示例 2:

输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。   
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。   
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。

示例 3:

输入:prices = [7,6,4,3,1] 
输出:0 
解释:在这个情况下, 没有交易完成, 所以最大利润为 0。

示例 4:

输入:prices = [1]
输出:0

思路:

1.确定dp数组以及下标的含义

一天一共就有五个状态,

1.没有操作 (其实我们也可以不设置这个状态)

2.第一次持有股票

3.第一次不持有股票

4.第二次持有股票

5.第二次不持有股票

dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金

2.确定递推公式

达到dp[i][1]状态,有两个具体操作:

1)操作一:第i天买入第一支股票了,那么dp[i][1] = dp[i-1][0] - prices[i]

2)操作二:第i天没有操作,而是沿用前一天买入第一支股票的状态,即:dp[i][1] = dp[i - 1][1]

达到dp[i][2]状态,有两个具体操作:

1)操作一:第i天卖出第一支股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]

2)操作二:第i天没有操作,沿用前一天卖出第一支股票的状态,即:dp[i][2] = dp[i - 1][2]

达到dp[i][3]状态,有两个具体操作:

dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);

达到dp[i][4]状态,有两个具体操作:

dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);

3.初始化

第0天没有操作,这个最容易想到,就是0,即:dp[0][0] = 0;

第0天做第一次买入的操作,dp[0][1] = -prices[0];

第0天做第一次卖出的操作,这个初始值应该是多少呢?

此时还没有买入,怎么就卖出呢? 其实大家可以理解当天买入,当天卖出,所以dp[0][2] = 0;

题条件是最多买两次

第0天只最多只能买一次,第二次买入操作,初始化为:dp[0][3] = -prices[0];

同理第二次卖出初始化dp[0][4] = 0;

4.确定遍历顺序

从递归公式其实已经可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值

5.举例推导

代码参考:

class Solution {
    public int maxProfit(int[] prices) {
      int[][] dp=new int[prices.length][5];
      //初始化
      dp[0][0]=0;
      dp[0][1]=-prices[0];
      dp[0][2]=0;
      dp[0][3]=-prices[0];
      dp[0][4]=0;
      for(int i=1;i<prices.length;i++){
        dp[i][0]=dp[i-1][0];
        dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
        dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+prices[i]);
        dp[i][3]=Math.max(dp[i-1][3],dp[i-1][2]-prices[i]);
        dp[i][4]=Math.max(dp[i-1][4],dp[i-1][3]+prices[i]);
      }
      return dp[prices.length-1][4];
    }
}

188. 买卖股票的最佳时机 IV

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

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

示例 2:

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

提示:

  • 1 <= k <= 100
  • 1 <= prices.length <= 1000
  • 0 <= prices[i] <= 1000

思路:

1.确定dp数组以及下标的含义

使用二维数组 dp[i][j] :第i天的状态为j,所剩下的最大现金是dp[i][j]

j的状态表示为:

  • 0 表示不操作
  • 1 第一次买入
  • 2 第一次卖出
  • 3 第二次买入
  • 4 第二次卖出
  • .....

题目要求是至多有K笔交易,那么j的范围就定义为 2 * k + 1 就可以了

2.确定递推公式

达到dp[i][1]状态,有两个具体操作:

1)操作一:第i天买入第一支股票了,那么dp[i][1] = dp[i-1][0] - prices[i]

2)操作二:第i天没有操作,而是沿用前一天买入第一支股票的状态,即:dp[i][1] = dp[i - 1][1]

达到dp[i][2]状态,有两个具体操作:

1)操作一:第i天卖出第一支股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]

2)操作二:第i天没有操作,沿用前一天卖出第一支股票的状态,即:dp[i][2] = dp[i - 1][2]

达到dp[i][3]状态,有两个具体操作:

dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);

达到dp[i][4]状态,有两个具体操作:

dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);

........同理可以类比剩下的状态

3.dp数组如何初始化

可以推出dp[0][j]当j为奇数的时候都初始化为 -prices[0]

4.确定遍历顺序

从递归公式其实已经可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

5.举例

k=2,prices=[1,2,3,4]

代码参考

class Solution {
    public int maxProfit(int k, int[] prices) {
     int[][] dp=new int[prices.length][2*k+1];
     //初始化
     for(int i=1;i<2*k;i=i+2){
        dp[0][i]=0-prices[0];
     }
     //
     for(int i=1;i<prices.length;i++){
        for(int j=1;j<2*k+1;j++){
            //奇数买入
            if(j%2==1)dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1]-prices[i]);
            //偶数卖出
            if(j%2==0)dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-1]+prices[i]);
        }
     }
     return dp[prices.length-1][2*k];
    }
}

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

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

相关文章

解码数据世界:统计学入门与应用指南

引言 统计学可以被定义为研究数据的科学&#xff0c;它涉及到数据的收集、分析、解释和呈现。其目标是从数据中提取有意义的信息&#xff0c;并使用这些信息来做出推断与决策。 统计学主要分别以下几个主要领域&#xff1a; 描述性统计&#xff1a;使用图表、图形和其他工具…

C++之入门

文章目录 1、前言2、C的关键字2.1C语言32关键字2.2C关键字(63个) 3、命名空间4、输入输出(cout、cin)4、缺省参数5、函数重载6 引用6.1 引用的定义6.2 引用的特性6.3引用的使用场景6.4 实际例子6.5、总结 7、内联函数8、auto关键字9、nullptr关键字 1、前言 C语言是结构化和模…

【声呐仿真】学习记录0-服务器配置docker、ros环境

【声呐仿真】学习记录0-服务器配置docker、ros环境 前言一、~~0.设置mobaXterm~~1.拉取镜像2.服务器开启xhost&#xff0c;可视化&#xff08;rviz、gazebo&#xff09;3.创建容器&#xff0c;挂载数据卷4.测试宿主机与容器数据是否同步5.测试5.0测试xclock5.1测试ros小乌龟5.2…

算术表达式计算程序:Python语言实现

算术表达式计算程序&#xff1a;Python语言实现 本文介绍通过Python语言实现算术表达式计算程序的过程。 我们将按照软件工程的基本步骤来介绍&#xff1a; 需求分析设计实现 程序的需求 我们的程序具有如下功能&#xff1a; 用户在提示符下输入一个算术表达式&#xff0…

碰到今日伦敦银价格走势图不懂得分析怎么办?

踏入2024年&#xff0c;伦敦银出现了比往年更多的投资机会&#xff0c;尤其是近期伦敦银价格连续上涨突破多个整数关口&#xff0c;现在已经站在28上方。碰到这么强的走势&#xff0c;投资者自然很想快点入场交易。但是交易前投资者需要分析今日伦敦银价格走势图之后再入场&…

ffmpeg支持MP3编码的方法

目录 现象 解决办法 如果有编译包没有链接上的情况 现象 解决办法 在ffmpeg安装包目录下 &#xff0c;通过./configure --list-encoders 和 ./configure --list-decoders 命令可以看到&#xff0c;ffmpeg只支持mp3解码&#xff0c;但是不支持mp3编码。 上网查寻后发现&…

idm序列号永久激活码2023免费可用 IDM软件破解版下载 最新版Internet Download Manager 网络下载加速必备神器 IDM设置中文

IDM是一款多线程下载工具&#xff0c;全称Internet Download Manager。IDM的多线程加速功能&#xff0c;能够充分利用宽带&#xff0c;所以下载速度会比较快&#xff0c;而且它支持断点续传。它的网站音视频捕获、站点抓取、静默下载等功能&#xff0c;也特别实用。 idm使用技…

SS34B-ASEMI超低Low VF肖特基SS34B

编辑&#xff1a;ll SS34B-ASEMI超低Low VF肖特基SS34B 型号&#xff1a;SS34B 品牌&#xff1a;ASEMI 封装&#xff1a;SMB 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;3A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;40V 最大正向电压…

hyperf 三十一 极简DB组件

一 安装及配置 composer require hyperf/db php bin/hyperf.php vendor:publish hyperf/db 默认配置 config/autoload/db.php 如下&#xff0c;数据库支持多库配置&#xff0c;默认为 default。 配置项类型默认值备注driverstring无数据库引擎 支持 pdo 和 mysqlhoststringl…

线程安全以及解决方案

文章目录 1.线程安全的原因①抢占式执行②多线程修改同一个变量③修改的操作不是原子的④内存可见性⑤指令重排序 2. 线程安全的解决方案3 synchronized的特性------可重入锁 1.线程安全的原因 ①抢占式执行 操作系统对线程的调度是随机的&#xff0c;没有规律&#xff08;主…

什么便签好用又没广告 好用无广便签分享

身处这个快节奏的时代&#xff0c;我们时常被各种琐事和计划所包围。想象一下&#xff0c;你在办公桌前&#xff0c;电脑屏幕上杂乱无章地贴着各种纸质便签&#xff0c;有的记录着待办事项&#xff0c;有的则是灵感闪现时的几句诗句。每次想要查找某个信息&#xff0c;都得费力…

Golang | Leetcode Golang题解之第42题接雨水

题目&#xff1a; 题解: func trap(height []int) (ans int) {n : len(height)if n 0 {return}leftMax : make([]int, n)leftMax[0] height[0]for i : 1; i < n; i {leftMax[i] max(leftMax[i-1], height[i])}rightMax : make([]int, n)rightMax[n-1] height[n-1]for i…

CANoe-Vector Security Manager介绍

Vector Security Manager 是 Vector 公司提供的一种工具,它为像 CANoe 这样的 Vector 工具提供安全功能,例如安全相关的通信(SecOC)、诊断、认证等,这些功能都是在安全配置文件中进行管理的。所有支持的工具都采用统一的配置方式。 一个安全配置文件为工具提供了以下安全…

探索AI时代的新天地:LLAMA3引领人工智能革命

大家好&#xff01;相信大家对于AI&#xff08;人工智能&#xff09;的发展已经有了一定的了解&#xff0c;但你是否意识到&#xff0c;到了2024年&#xff0c;AI已经变得如此强大和普及&#xff0c;带来了我们从未想象过的便利和创新呢&#xff1f;让我们一起来看看AI在这个时…

如何安全高效地进行网点文件下发?

随着IT技术的飞速发展&#xff0c;以银行为代表的企业数字化技术转型带来了大量的电子化文档传输需求。文件传输数量呈几何级数增长&#xff0c;传统集中式文件传输模式在爆炸式的增长需求下&#xff0c;银行网点文件下发的效率、可靠性、安全性等方面&#xff0c;都需要重点关…

边缘计算的优势

边缘计算的优势 边缘计算是一种在数据生成地点附近处理数据的技术&#xff0c;而非传统的将数据发送到远端数据中心或云进行处理。这种计算模式对于需要快速响应的场景特别有效&#xff0c;以下详述了边缘计算的核心优势。 1. 降低延迟 边缘计算通过在数据源近处处理数据&…

2款摄像头录像软件,满足你的多种要求!

“有没有一款能够录制摄像头视频的软件呀&#xff1f;我计划录制一些生活小窍门和教学视频&#xff0c;想要能清楚地拍到自己的操作过程。但找了好多软件&#xff0c;都不太满意&#xff0c;真心希望大家能给我推荐几款好用的摄像头录像软件&#xff0c;最好能简单易上手的&…

GPU功能介绍简介

GPU功能介绍简介 随着计算需求的不断升级&#xff0c;尤其是在图形密集型和并行计算任务中&#xff0c;GPU已经从一个简单的图像渲染器件演变成一个强大的计算工具。本篇文章将深入探讨GPU的核心功能、架构以及其在多个领域中的应用。 一、GPU的起源与演进 GPU最初设计用于加速…

百兆集成网络链接器911105A

百兆集成网络链接器&#xff08;有时也称为百兆网卡&#xff09;是一种硬件设备&#xff0c;主要用于计算机与计算机网络之间的高速数据传输。它的主要功能包括&#xff1a; 1. 高速数据传输&#xff1a;百兆集成网络链接器支持100Mbps的数据传输速率&#xff0c;比之前的以太…

抖音老阳讲的选品师项目普通人能赚钱吗?

随着互联网的快速发展&#xff0c;电商行业也迎来了前所未有的繁荣。在这个背景下&#xff0c;选品师这一职业逐渐走进人们的视野。老阳作为行业内的知名人士&#xff0c;经常分享选品师的经验和项目。那么&#xff0c;普通人能否参与老阳讲的选品师项目并且赚钱吗?答案是肯定…