代码随想录算法训练营第41天|LeetCode 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II、123.买卖股票的最佳时机III

server/2024/10/18 8:23:13/

1. LeetCode 121. 买卖股票的最佳时机

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/
文章链接:https://programmercarl.com/0121.买卖股票的最佳时机.html#思路
视频链接:https://www.bilibili.com/video/BV1Xe4y1u77q

在这里插入图片描述

思路:
1.确定dp数组(dp table)以及下标的含义。
dp[i][0] 表示第i天持有股票所得最多现金;
dp[i][1] 表示第i天不持有股票所得最多现金。
2.确定递推公式
1️⃣如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0];
第i天买入股票,所得现金就是买入今天的股票后所得现金即:-prices[i]
那么dp[i][0]应该选所得现金最大的,所以dp[i][0] = max(dp[i - 1][0], -prices[i]);
2️⃣如果第i天不持有股票即dp[i][1], 也可以由两个状态推出来
第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]
那么dp[i][1]取最大的,dp[i][1] = max(dp[i - 1][1], prices[i] + dp[i - 1][0]);
3.初始化
dp[0][0] -= prices[0];
dp[0][1] = 0;
4.遍历顺序
从前向后遍历。

解法:
class Solution {public int maxProfit(int[] prices) {if (prices.length==0 || prices.length==1) return 0;//1.定义dp数组 //dp[i][0]表示第i天持有股票金额//dp[i][1]表示第i天不持有股票金额int[][] dp = new int[prices.length][2];//2.递推公式//dp[i][0] = Math.max(dp[i-1][0],-prices[i]);//dp[i][1] = Math.max(dp[i-1][1],prices[i]+dp[i-1][0]);//3.初始化dp[0][0]=-prices[0];dp[0][1]=0;//4.遍历顺序for (int i=1;i<prices.length;i++) {dp[i][0] = Math.max(dp[i-1][0],-prices[i]);dp[i][1] = Math.max(dp[i-1][1],prices[i]+dp[i-1][0]);}return dp[prices.length-1][1];}
}

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

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/
文章链接:https://programmercarl.com/0122.买卖股票的最佳时机II(动态规划).html
视频链接:https://www.bilibili.com/video/BV1D24y1Q7Ls

在这里插入图片描述

思路:
本题和121. 买卖股票的最佳时机 (opens new window)的唯一区别是本题股票可以买卖多次了(注意只有一只股票,所以再次购买前要出售掉之前的股票)
递推公式:
1️⃣如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来:
第i-1天就持有股票,那么就保持现状,所得现金就是昨天持有股票的所得现金 即:dp[i - 1][0]
第i天买入股票,所得现金就是昨天不持有股票的所得现金减去 今天的股票价格 即:dp[i - 1][1] - prices[i]
2️⃣如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来:
第i-1天就不持有股票,那么就保持现状,所得现金就是昨天不持有股票的所得现金 即:dp[i - 1][1]
第i天卖出股票,所得现金就是按照今天股票价格卖出后所得现金即:prices[i] + dp[i - 1][0]

class Solution {// // 贪心// public int maxProfit(int[] prices) {//     int res = 0;//     for (int i=1;i<prices.length;i++) {//         if (prices[i]-prices[i-1] > 0) {//             res += (prices[i]-prices[i-1]);//         }//     }//     return res;// }// //动态规划 1// public int maxProfit(int[] prices) {//     //1.定义dp数组//     //dp[i]表示第i天的最大利润//     int[] dp = new int[prices.length];//     //2.递推公式//     //dp[i]=Math.max(dp[i-1],dp[i-1]+(prices[i]-prices[i-1]));//     //3.初始化//     dp[0]=0;//     //4.遍历顺序//     for (int i=1;i<prices.length;i++) {//         dp[i]=Math.max(dp[i-1],dp[i-1]+(prices[i]-prices[i-1]));//     }//     return dp[prices.length-1];// }//动态规划 2public int maxProfit(int[] prices) {//1.定义dp数组//dp[i][0]表示第i天持有股票的金额//dp[i][1]表示第i天不持有股票的金额int[][] dp = new int[prices.length][2];//2.递推公式//dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);//dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);//3.初始化dp[0][0]=-prices[0];dp[0][1]=0;//4.遍历顺序for (int i=1;i<prices.length;i++) {dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]-prices[i]);dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]+prices[i]);}return dp[prices.length-1][1];}
}

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

题目链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/description/
文章链接:https://programmercarl.com/0123.买卖股票的最佳时机III.html
视频链接:https://www.bilibili.com/video/BV1WG411K7AR

在这里插入图片描述

思路:
关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。

1.确定dp数组以及下标的含义
一天一共就有五个状态:
0 没有操作 (其实我们也可以不设置这个状态)
1 第一次持有股票时的金额
2 第一次不持有股票时的金额
3 第二次持有股票时的金额
4 第二次不持有股票时的金额
dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。
2.确定递推公式
1️⃣dp[i][1]状态表示第i天第一次持有股票时的金额,有两个具体操作:
操作一:第i天买入股票了,那么dp[i][1] = - prices[i]
操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][1] = dp[i - 1][1]
选最大的,则递推公式为:dp[i][1] = max(-prices[i], dp[i - 1][1]);
2️⃣dp[i][2]状态表示第i天第一次不持有股票时的金额,有两个操作:
操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]
操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][2] = dp[i - 1][2]
选最大的,则递推公式为:p[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2]);
3️⃣dp[i][3]状态表示第i天第二次持有股票时的金额,有两个具体操作:
操作一:第i天买入股票了,那么dp[i][3] = dp[i-1][2] - prices[i]
操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][3] = dp[i - 1][3]
选最大的,则递推公式为:dp[i][3] = max(dp[i-1][2] - prices[i], dp[i - 1][3]);
4️⃣dp[i][4]状态表示第i天第二次不持有股票时的金额,有两个操作:
操作一:第i天卖出股票了,那么dp[i][4] = dp[i - 1][3] + prices[i]
操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][4] = dp[i - 1][4]
选最大的,则递推公式为:p[i][4] = max(dp[i - 1][3] + prices[i], dp[i - 1][4]);
3.dp数组如何初始化
dp[0][0]=0;
dp[0][1]=-prices[0];
dp[0][2]=0;
dp[0][3]=-prices[0];
dp[0][4]=0;
4.确定遍历顺序
从递归公式其实已经可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

class Solution {public int maxProfit(int[] prices) {//1.定义dp数组//dp[i][0] 第i天没有操作//dp[i][1] 第i天第一次持有股票时的金额//dp[i][2] 第i天第一次不持有股票时的金额//dp[i][3] 第i天第二次持有股票时的金额//dp[i][4] 第i天第二次不持有股票时的金额int[][] dp = new int[prices.length][5];//2.递推公式//dp[i][1]=Math.max(dp[i-1][1],-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]);//3.初始化dp[0][0]=0;dp[0][1]=-prices[0];dp[0][2]=0;dp[0][3]=-prices[0];dp[0][4]=0;//4.遍历顺序 从前往后for (int i=1;i<prices.length;i++) {dp[i][1]=Math.max(dp[i-1][1],-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];}
}

http://www.ppmy.cn/server/93309.html

相关文章

第1-3章Excel数据分析基础

文章目录 第1章&#xff1a;使用统计函数做数据分析1-1常用统计函数应用1-2条件统计函数1-3多条件统计函数1-4条件统计函数中的通配符1-5将条件统计函数中的条件数组化1-6单条件文本合并-新增函数1-7多条件与模仿通配符的文本合并 第2章&#xff1a;数据分析之合并计算2-1合并计…

在linux上部署MySQL(源码安装)

1&#xff09;我们拿到一个新的centos系统是先安装 &#xff1b; yum install -y wget 2&#xff09;然后安装wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm &#xff08;这里我们安装的是mysql7.5&#xff09; wget http://dev.mysql.com/get/m…

uniapp小程序中富文本内容渲染图片不展示的问题

文章目录 1.从后端请求的数据中图片是这样的2.前端我是用Uview中的u-parse组件3.这样修改去掉富文本中的所有反斜杠4.完美解决 1.从后端请求的数据中图片是这样的 <p><img src\\\"https://zhangsanfengcode.cn:8084/images/2024-06-28a257befe.jpg\\\" alt…

tcp为啥是三次握手,不是四次、两次?

TCP&#xff08;传输控制协议&#xff09;使用三次握手过程来建立一个可靠的连接&#xff0c;主要原因包括以下几点&#xff1a; 1. **数据包的不可靠性**&#xff1a;在网络中传输的数据包可能会丢失、延迟或乱序。TCP 需要确保数据能够可靠地传输到目的地。 2. **同步连接状…

基于GitHub page和Hexo主题搭建个人博客(win)

1.安装git git官网下载地址&#xff1a;Git - Downloads (git-scm.com) (1)下载&#xff1a;进入官网&#xff0c;选择对应版本下载&#xff0c;得到.exe文件 (2)安装&#xff1a;打开.exe文件&#xff0c;进行如下操作 (3)安装好后&#xff0c;右击鼠标&#xff0c;点击显示…

成为git砖家(4): git status 命令简介

1. untracked 和 tracked 状态 Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot, as well as any newly staged files; they can be unmodified, modified, o…

C# 写入SQLServer数据库报错SqlException: 不能将值 NULL 插入列 ‘ID‘

private int id; [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]//id自增 public int ID { get > id; set > id value; } 将ID属性下的标识规范由否改成是

学习大数据DAY24 Shell脚本的书写

目录 shell 的变量 系统变量 特殊变量 运算符 if 选择结构 ---then 独立一行 case 语句 等值判断 上机练习 10 附加题 for 循环 while 循环 乘法表(双层嵌套) 上机练习 11 把附加题代码修改为循环形式 shell 的变量 系统变量 $HOME : 当前登录用户的 " 家…