【力扣】买卖股票(121,122,123)

121. 买卖股票的最佳时机

题意

  • 只能买卖股票各一次
  • 求最大收益

解法 动态规划

要求最值,肯定要穷举。而穷举主要有两种方法:动态规划回溯

这道题显然可以使用动态规划的算法来解决,因为这里有一个很明显的子问题:前 i i i 天的最大利润 = = = i i i 天的价格 − - ( i − 1 ) (i - 1) (i1) 天的最小值。其中,求前 i i i 天的最小值可以使用动态规划来求解

求前 i i i 天的最小值 :

  • 状态变量: tmp[i] 表示前 i i i 天的最小值,其中, 0 < = i < = n 0 <= i <= n 0<=i<=n
  • 初始状态:tmp[0] = INT_MAX;
  • 状态转移方程:tmp[i] = min(tmp[i - 1], prices[i - 1]);

注意:由于状态变量 tmp 需要赋一个初始值,所以 tmp 的有效下标为 0 − n 0 - n 0n,其中 1 − n 1 - n 1n 对应 prices 的 0 − ( n − 1 ) 0 - (n - 1) 0(n1)

class Solution {
public:int minPrice(vector<int>& prices) {vector<int> tmp(prices.size() + 1, 0);tmp[0] = 1e9;for(int i = 1; i <= prices.size(); i++){tmp[i] = min(tmp[i - 1], prices[i - 1]);}return tmp[prices.size()];}
};

那么,最大收益也就可以解决了:

class Solution {
public:int maxProfit(vector<int>& prices) {vector<int> tmp(prices.size() + 1, 0);tmp[0] = 1e9;int ans = 0;for(int i = 1; i <= prices.size(); i++){tmp[i] = min(tmp[i - 1], prices[i - 1]);ans = max(ans, prices[i - 1] - tmp[i]);}return ans;}
};

但是,考虑到 tmp[i] 的状态转移只与 tmp[i - 1]有关,因此可以只用一个变量来代替 tmp[]

class Solution {
public:int maxProfit(vector<int>& prices) {int tmp = 1e9;int ans = 0;for(int i = 1; i <= prices.size(); i++){tmp = min(tmp, prices[i - 1]);ans = max(ans, prices[i - 1] - tmp);}return ans;}
};

复杂度

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


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

题意

  • 每天最多只能持有一只股
  • 可多次买卖
  • 求最大收益

解法 动态规划

这道题与上一题的变化在于,状态变多了。对于每天来说,一共有两个状态:持有股票 或者 未持有股票,一共有三种操作可以进行状态转移:不操作买入卖出

  • 状态变量: dp[i][2]dp[i][0] 表示第 i i i 天未持有股票时获得的最大利润,dp[i][1]表示第 i i i 天持有股票时获得的最大利润,其中, 0 < = i < = n 0 <= i <= n 0<=i<=n 0 0 0 对应初始化, 1 − n 1 - n 1n 对应 p r i c e s [ 0 ] − p r i c e s [ n − 1 ] prices[0] - prices[n - 1] prices[0]prices[n1]
  • 初始状态:dp[0][0] = 0, dp[0][1] = -prices[0];,其中,要想在第 0 0 0 天就持有股票,那只能持有 p r i c e s [ 0 ] prices[0] prices[0],并且此时利润为负。
  • 状态转移方程:
    • 如果当天没有股票,可能是前一天也没有股票(不进行操作),或者前一天持有股票而当天卖出(卖出操作);
    • 如果当天持有股票,可能是前一天就持有股票(不进行操作),或者前一天没有股票而当天买入(买入操作);
    • 因此,状态转移方程如下:
      dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i - 1]);
      dp[i][1] = max(dp[i - 1][0] - prices[i - 1], dp[i - 1][1]);
class Solution {
public:int maxProfit(vector<int>& prices) {int n = prices.size();vector<vector<int>> dp(n + 1, vector<int>(2));dp[0][0] = 0;dp[0][1] = -prices[0];for(int i = 1; i <= n; i++){dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i - 1]);dp[i][1] = max(dp[i - 1][0] - prices[i - 1], dp[i - 1][1]);}return max(dp[n][0], dp[n][1]);}
};

复杂度

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


买卖股票的最佳时机 III

题意

  • 最多只能进行两次买卖,且只有结束了一次买卖,才能开启下一次买卖
  • 求最大利润

解法 动态规划

关于这道题,第一想法是暴力。因此一共只有两次买卖,所以将 prices[] 分成两段,对于两段分别进行最多一次买卖的最大利润的求取,然后将两次利润相加得到答案,这样就转换成了 121 题。

但是看了看数据范围,这样的做法,复杂度为 O ( n 2 ) O(n^2) O(n2),显然会超时。

代码如下:

class Solution {
public:int subMaxProfit(vector<int>& prices, int st, int end){int tmp = prices[st];int ans = 0;for(int i = st; i <= end; i++){tmp = min(tmp, prices[i]);ans = max(ans, prices[i] - tmp);}return ans;}int maxProfit(vector<int>& prices) {int pro1 = 0, pro2 = 0;int n = prices.size();int ans = 0;for(int i = 0; i < prices.size(); i++){pro1 = subMaxProfit(prices, 0, max(i, 0));pro2 = subMaxProfit(prices, min(i + 1, n - 1), n - 1);ans = max(ans, pro1 + pro2);}return ans;}
};

果然超时。

所以还是选择 列举状态,构建状态转移方程

一共有 5 种状态

  • 未买卖过
  • 买一次
  • 买一次,卖一次
  • 买一次,卖一次,买一次
  • 买一次,卖一次,买一次,卖一次

然后构建状态转移方程

  • 状态变量: buy1sell1buy2sell2,第一种状态可以单纯用 0 来表示(因为没有利润为 0 )。
  • 初始状态:buy1 = -prices[0]sell1 = 0buy2 = -prices[0]sell2 = 0。其中,sell1 = 0 表示买入 prices[0],再卖出 prices[0]sell2 = 0 表示买入 prices[0],再卖出 prices[0],再买入 prices[0],再卖出 prices[0]
  • 状态转移方程:
    sell2 = max(buy2 + p, sell2);
    buy2 = max(sell1 - p, buy2);
    sell1 = max(buy1 + p, sell1);
    buy1 = max(buy1, -p);

ps. 这里为了防止每一轮中 先更新的变量 影响 后更新的变量 的更新,我特意调整了更新顺序,保证每一个变量更新时,等号右边的状态变量都是上一轮的值。(但是不调整顺序似乎也不影响 ac?)

class Solution {
public:int maxProfit(vector<int>& prices) {int buy1 = -prices[0], sell1 = 0, buy2 = -prices[0], sell2 = 0;for(auto p : prices){sell2 = max(buy2 + p, sell2);buy2 = max(sell1 - p, buy2);sell1 = max(buy1 + p, sell1);buy1 = max(buy1, -p);}return max(0, max(sell1, sell2));}
};

复杂度

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


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

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

相关文章

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …

【高阶数据结构】哈希(哈希表、哈希桶)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C进阶 ⭐代码仓库&#xff1a;C进阶 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…

微服务技术栈-认识微服务和第一个微服务Demo

文章目录 前言一、认识微服务二、微服务技术栈三、Eureka注册中心四、微服务DEMO1、搭建eureka-server2、服务注册和服务发现 总结 前言 随着业务的不断复杂&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。 本章就从微服…

VD6283TX环境光传感器驱动开发(1)----获取ID

VD6283TX环境光传感器驱动开发----1.获取ID 概述视频教学样品申请源码下载模块参数IIC接线方式设备ID生成STM32CUBEMX串口配置 IIC配置串口重定向模块地址获取ID主函数结果演示 概述 环境光传感器是一种光电探测器&#xff0c;能够将光转换为电压或者电流&#xff0c;使用多光…

计算机网络常见面试题

梳理计算机网络相关的面试题&#xff0c;相关知识结构主要参考谢希仁老师的《计算机网络&#xff08;第五版&#xff09;》一书&#xff0c;并整理互联网上常见面试题。 计算机网络性能指标 性能指标从不同的方面来度量计算机网络的性能。下面介绍常用的七个性能指标。 1、速…

23-properties文件和xml文件以及dom4j的基本使用操作

特殊文件 我们利用这些特殊文件来存放我们 java 中的数据信息&#xff0c;当数据量比较大的时候&#xff0c;我们可以利用这个文件对数据进行快速的赋值 对于多个用户数据的存储的时候我们要用这个XML来进行存储 关于这些特殊文件&#xff0c;我们主要学什么 了解他们的特点&…

华为云云耀云服务器L实例评测 | 实例使用教学之软件安装:华为云云耀云服务器环境下安装 Docker

华为云云耀云服务器L实例评测 &#xff5c; 实例使用教学之软件安装&#xff1a;华为云云耀云服务器环境下安装 Docker 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀云…

想要精通算法和SQL的成长之路 - 验证二叉搜索树和不同的二叉搜索树

想要精通算法和SQL的成长之路 - 验证二叉搜索树和不同的二叉搜索树 前言一. 验证二叉搜索树二. 不同的二叉搜索树三. 不同的二叉搜索树II 前言 想要精通算法和SQL的成长之路 - 系列导航 二叉搜索树的定义&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包…

【前段基础入门之】=>CSS浮动

浮动的简介 在最初&#xff0c;浮动是用来实现文字环绕图片效果的&#xff0c;现在浮动是主流的页面布局方式之一。 元素浮动后的特点 &#x1f922; 脱离文档流。&#x1f60a; 不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽…

GRACE-FO L2产品的发布说明 - 版本UTCSR RL-06.1产品

数据更新日期&#xff1a;2023-5-11 0&#xff09;此说明取代了所有先前与UTCSR-RL06.1 GRACE-FO Level-2产品相关的旧版本发布说明。 1&#xff09;截止到本发布说明日期的GRACE-FO RL-06.1产品文件列表如下&#xff1a; 2&#xff09;通常情况下&#xff0c;每个日历月有四…

游戏逆向中的 NoClip 手段和安全应对方式

文章目录 墙壁边界寻找碰撞 NoClip 是一种典型的黑客行为&#xff0c;允许你穿过墙壁&#xff0c;所以 NoClip 又可以认为是避免碰撞体积的行为 墙壁边界 游戏中设置了碰撞体作为墙壁边界&#xff0c;是 玩家对象 和墙壁发生了碰撞&#xff0c;而不是 相机 玩家对象有他的 X…

从 0 到 1 ,手把手教你编写《消息队列》项目(Java实现) —— 核心类持久化存储

文章目录 一、持久化存储的方式与路径二、公共模块序列化 / 反序列化异常规定 三、持久化存储数据库数据管理文件数据管理读写规定新增 /删除规定内存中 Message 的规定存储规定代码编写 硬盘数据管理 一、持久化存储的方式与路径 交换机,队列,绑定关系,这些我们使用数据库来管…

警用装备管理系统|智装备DW-S304的主要功能

东识科技&#xff08;DONWIT&#xff09;警用装备管理系统DW-S304是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 在国外很早开始便使用警用装备管理系统对警用装备的管理使用进行…

Explain执行计划字段解释说明---select_type、table、patitions字段说明

1、select_type的类型有哪些 2、select_type的查询类型说明 1、SIMPLE 简单的 select 查询,查询中不包含子查询或者UNION 2、PRIMARY 查询中若包含任何复杂的子部分&#xff0c;最外层查询则被标记为Primary 3、DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生)&…

基于ssm的互联网废品回收/基于web的废品资源利用系统

摘 要 本毕业设计的内容是设计并且实现一个基于SSM框架的互联网废品回收。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。互联网废品回收的功能已基本实现&#xff0c;主要包括用户、回收员、物品分类、回收物品、用户下单…

【Python 基础 2023 最新】第七课 Pandas

【Python 基础 2022 最新】第七课 Pandas 概述Pandas 是什么?Pandas 的应用场景安装 Pandas Pandas 数据结构Series 数组什么是 Series?Series 创建 Series 数组操作数据检索数据修改过滤Series 数组运算总结 什么是 DataFrameDataFrame 创建 DataFrame 操作数据检索筛选数据…

决策树C4.5算法的技术深度剖析、实战解读

目录 一、简介决策树&#xff08;Decision Tree&#xff09;例子&#xff1a; 信息熵&#xff08;Information Entropy&#xff09;与信息增益&#xff08;Information Gain&#xff09;例子&#xff1a; 信息增益比&#xff08;Gain Ratio&#xff09;例子&#xff1a; 二、算…

密码技术 (6) - 证书

一. 前言 前面介绍的公钥密码和数字签名&#xff0c;都无法解决一个问题&#xff0c;那就是判断自己获取的公钥是否期望的&#xff0c;不能确定公钥是否被中间攻击人掉包。所以&#xff0c;证书的作用是用来证明公钥是否合法的。本文介绍的证书就是解决证书的可靠性的技术。 二…

最新反编译小程序教程(支持分包一键反编译),反编译成功率高达99%

最新反编译小程序教程&#xff08;支持分包一键反编译&#xff09;&#xff0c;反编译成功率高达99% 优点&#xff1a; 1.支持多个分包以及主包一次性反编译&#xff1b; 2.使用wxappUnpacker无法进行解析的小程序包&#xff0c;一键反编译解析&#xff08;咱没有发现反编译失败…

使用ExLlamaV2在消费级GPU上运行Llama2 70B

Llama 2模型中最大也是最好的模型有700亿个参数。一个fp16参数的大小为2字节。加载Llama 270b需要140 GB内存(700亿* 2字节)。 只要我们的内存够大&#xff0c;我们就可以在CPU上运行上运行Llama 2 70B。但是CPU的推理速度非常的慢&#xff0c;虽然能够运行&#xff0c;速度我…