面试必刷算法TOP101之买卖股票问题 TOP16
一个思路解决下边买卖股票的问题
首先先分析下边的问题
121. 买卖股票的最佳时机 I 限定交易次数 k=1
122. 买卖股票的最佳时机 II 交易次数无限制 k = N
123. 买卖股票的最佳时机 III 限定交易次数 k=2
124. 买卖股票的最佳时机 IV 限定交易次数 最多次数为 k k还是有限制的
这些问题都是买卖股票的最佳时机,都是在通过买卖股票的来获取最大差值大,但是最大区别就是买卖股票的次数都是不一样的,所以将这些问题看作是一个问题,只不过是对于不同问题交易次数是不同的,因为是动态规划问题还是使用PD的解题步骤来解决问题:
(1)创建dp数组明确下标的含义
创建一个三维数组dp[i][k][j]其含义是在第i天剩余叫次数还有k次,对于j来说不是0就是1,0代表没有股票,1代表持有股票,具体含义如下:
dp[i][k][0] 第i天 还可以交易k次 手中没有股票
dp[i][k][1] 第i天 还可以交易k次 手中有股票
最后的结果应该是dp[i][k][0]手中应该没有持有股票,因为最后一天持有股票的化没有卖出其收益肯定不是最高的
(2)递推公式
因为定义dp数组时定义第i天持有股票和没有持有股票所以分为两种情况
第i天没有持有股票,可以分为两种情况
递推公式为:dp[i][k][0] = max(dp[i - 1][k][0], dp[i - 1][k][1] + cost[i])
// 今天没有持有股票,分为两种情况
// 1. dp[i - 1][k][0],昨天没有持有,今天不操作。
// 2. dp[i - 1][k][1] + prices[i] 昨天持有,今天卖出,今天手中就没有股票了。
第i天持有股票,可以分为两种情况
递推公式为:p[i][k][1] = max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - cost[i]
// 今天持有股票,分为两种情况:
// 1.dp[i - 1][k][1] 昨天持有,今天不操作
// 2.dp[i - 1][k - 1][0] - prices[i] 昨天没有持有,今天买入。
最大利益就是将持股与不持股情况比较去一个最大值
(3)初始化‘
每个问题的情况不一样初始化也是不样的
(4)遍历顺序
因为都是前边买入后边卖出所以遍历方式自然就是从前往后
股票问题以之 买卖股票的最佳时机Ⅰ
题目来源:Leetcode
1、问题描述
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
2、转移方程式
前边已经总结出来大的思路但是每一个问题,还有一些是不同的针对这个问题还是要具体分析
转移方程
//第i天不持有 由 第i-1天不持有然后不操作 和 第i-1天持有然后卖出 两种情况的最大值转移过来
dp[i][1][0] = max(dp[i - 1][1][0], dp[i - 1][1][1] + cost[i])
//第i天持有 由 第i-1天持有然后不操作 和 第i-1天不持有然后买入 两种情况的最大值转移过来
dp[i][1][1] = Math.max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])
= max(dp[i - 1][1][1], -cost[i]) // k=0时 没有交易次数,dp[i - 1][0][0] = 0
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - cost[i]
dp[i][[1] = max(dp[i - 1][1], cost[i]) k=0时 没有交易次数,dp[i - 1][0][0] = 0
简化为一个二为数组但是结果还是不影响
3.代买实现
``
class Solution {
public:
int maxProfit(vector<int>& prices) {int n = prices.size();int dp[n][2];dp[0][0] = 0;dp[0][1] = -prices[0];//因为第0天买入的话就持股就是-prices[0]for (int i = 1; i < n; ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = max(dp[i - 1][1], - prices[i]);}return dp[n - 1][0];
}
};
前边代码dp[i]之与dp[i-1]有关可以将dp数组降维到一维数组```kotlin
int maxProfit(vector<int>& prices) {int n = prices.size();int dp[2];dp[0] = 0;dp[1] = -prices[0];//因为第0天买入的话就持股就是-prices[0]for (int i = 1; i < n; ++i) {dp[0] = max(dp[0], dp[1] + prices[i]);dp[1] = max(dp[1], - prices[i]);}return dp[0];}
股票问题以之 买卖股票的最佳时机Ⅱ
题目来源:Leetcode
1、问题描述
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回 你能获得的 最大 利润 。
2、转移方程式
//第i天不持有 由 第i-1天不持有然后不操作 和 第i-1天持有然后卖出 两种情况的最大值转移过来
dp[i][1][0] = max(dp[i - 1][1][0], dp[i - 1][1][1] + cost[i])
//第i天持有 由 第i-1天持有然后不操作 和 第i-1天不持有然后买入 两种情况的最大值转移过来
dp[i][1][1] = Math.max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - cost[i]
dp[i][[1] = max(dp[i - 1][1], dp[i - 1][0][0] -cost[i])
3代码实现
int maxProfit(vector<int>& prices) {int n = prices.size();int dp[2];dp[0] = 0;dp[1] = -prices[0];//因为第0天买入的话就持股就是-prices[0]for (int i = 1; i < n; ++i) {dp[0] = max(dp[0], dp[1] + prices[i]);dp[1] = max(dp[1], - prices[i]);}return dp[0];}
买卖股票的最佳时机Ⅲ
题目来源:Leetcode
1、问题描述
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
2、转移方程式
//第i天不持有 由 第i-1天不持有然后不操作 和 第i-1天持有然后卖出 两种情况的最大值转移过来
dp[i][1][0] = max(dp[i - 1][1][0], dp[i - 1][1][1] + cost[i])
//第i天持有 由 第i-1天持有然后不操作 和 第i-1天不持有然后买入 两种情况的最大值转移过来
dp[i][1][1] = Math.max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])
K对结果有影响不能舍弃
对其循环
for (let i = 0; i < n; i++) {for (let k = maxK; k >= 1; k--) {dp[i][k][0] = Mmax(dp[i - 1][k][0], dp[i - 1][k][1] + prices[i]);dp[i][k][1] = max(dp[i - 1][k][1], dp[i - 1][k - 1][0] - prices[i]);}
}
先写出i为2和1时的结果
i为2时
dp[i][1][0] = max(dp[i - 1][1][0], dp[i - 1][1][1] + cost[i])
dp[i][1][1] = Math.max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])
还是这样
.
…
i为1时
就成了买卖股票的最佳时机的情况
因为当k==0时没有交易次数,dp[i - 1][0][0] = 0所以就会出现如下情况;
dp[i][1][1] = max(dp[i - 1][1][1], dp[i - 1][0][0] - prices[i])
= max(dp[i - 1][1][1], -cost[i])
dp[i][1][0] = max(dp[i - 1][1][0], dp[i - 1][1][1] + cost[i])去掉中间这一维
dp[i][1][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
= max(dp[i - 1][1], -cost[i])
dp[i][1][0] = max(dp[i - 1][0], dp[i - 1][1] + cost[i])
3代买实现
//和前面一样 我们直接降维int maxProfit(vector<int>& prices) {int buy_1 = -prices[0], sell_1 = 0;int buy_2 = -prices[0], sell_2 = 0;int n = prices.size();for (int i = 1; i < n; i++) {sell_2 = max(sell_2, buy_2 + prices[i]);buy_2 = max(buy_2, sell_1 - prices[i]);sell_1 = max(sell_1, buy_1 + prices[i]);buy_1 = max(buy_1, -prices[i]);}return sell_2;}
面试必刷算法TOP101之买卖股票问题 TOP16相关推荐
- 面试必刷算法TOP101之图算法篇 TOP37
最长递增路径 题目来源:leetcode 1.问题描述 给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度. 对于每个单元格,你可以往上,下,左,右四个方向移动. 不能 在 ...
- 【算法面试必刷JAVA版三】链表中的节点每k个一组翻转
盲目刷题,浪费大量时间,博主这里推荐一个面试必刷算法题库,刷完足够面试了.传送门:牛客网面试必刷TOP101
- 【算法面试必刷Java版八】链表中倒数最后k个结点
盲目刷题,浪费大量时间,博主这里推荐一个面试必刷算法题库,刷完足够面试了.传送门:牛客网面试必刷TOP101
- 【算法面试必刷JAVA版二】链表内指定区间反转
盲目刷题,浪费大量时间,博主这里推荐一个面试必刷算法题库,刷完足够面试了.传送门:牛客网面试必刷TOP101
- 【算法面试必刷Java版七】链表中环的入口结点
盲目刷题,浪费大量时间,博主这里推荐一个面试必刷算法题库,刷完足够面试了.传送门:牛客网面试必刷TOP101
- 【算法面试必刷Java版九】删除链表的倒数第n个节点
盲目刷题,浪费大量时间,博主这里推荐一个面试必刷算法题库,刷完足够面试了.传送门:牛客网面试必刷TOP101
- 【牛客网面试必刷TOP101】链表篇(一)
链表 一.前言 二.学习刷题网站 1.推荐的原因 三.刷题 <1>反转链表 递归法 <2>链表内指定区间反转 ①头插法 ②递归法 <3>链表中的节点每k个一组翻转 ...
- python必刷面试_Python面试必刷题系列(5)
本篇是[Python面试必刷题系列]的第5篇文章.通过收集.整理Python真实面试题,给大家讲解面试中的python高频考察点,希望能够引起读者的足够重视. 往期回顾: Python中 is 和 = ...
- 《LeetCode刷题》—121. 买卖股票的最佳时机
<LeetCode刷题>-121. 买卖股票的最佳时机 一.题目内容 原题连接:https://leetcode.cn/problems/best-time-to-buy-and-sell ...
- 算法套路十七——买卖股票问题:状态机 DP
算法套路十七--买卖股票问题:状态机 DP 状态机DP是一种将动态规划方法应用于有限状态机(Finite State Machine)的问题求解方法. 状态机DP(State Machine DP)是 ...
最新文章
- iOS 9应用开发教程之定制应用程序图标以及真机测试
- 熟悉Linux的环境实验报告,实验1 熟悉Linux开发环境 实验报告
- windows server 2008 让domain user有本地administrator权限
- getopt java_使用 Getopt::Std 的命令行开关
- 用phpcms如何将静态页面制作成企业网站(下)
- Getting Contexts 获得上下文
- 15款优雅的 WordPress 电子商务网站主题
- use texstudio with chinese on ubuntu
- Windows Server 2003安装应用程序时,提示缺失kernel.dll文件
- TCP/UDP的区别
- 【Xcelsius】在PPT中嵌入水晶易表Xcelsius2008仪表盘
- xp如何删除计算机管理员用户账户,“WINXP系统除Administrator以外只有一个管理员账户时,此帐户默认无法删除,如何删除”的解决方案...
- 深入解读RFM模型-实战应用干货
- 计算机发展史评课议课稿,历史课评课稿
- b站网页版没有html,b站网页版
- 神经网络与机器学习 pdf 全文内容详细分享
- 谷歌账户二次验证_为您的Google帐户和Microsoft帐户设置双重身份验证
- 请和我一起学习机器学习算法(决策树)
- 山东省有哪些计算机专业大学排名,山东人工智能专业大学排名
- 华为OJ基础题-学英语