面试热题100(买卖股票的最佳时机)

news2025/1/15 6:27:20

       为什么有人夜里碰到股票问题,辗转反侧睡不着觉?为什么有人看到股票问题心理欢喜直接操作?你是想做哪类人?今天就揭秘股票问题,让你应对股票问题的时候可以如鱼得水。

       这种问题一看就是动态规划问题,动态规划说难听一点就是穷举,但是我们应该如何的去聪明的穷举,这是我们需要考虑的

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

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

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

      股票l只是进行了一次交易,相当于k=1;股票II相当于不限制交易次数,k=inf;股票III只是进行了2次交易,相当于k=2;剩下的题目也是不限次数,但是增加了一些额外的条件,其实解题步骤也是大差不差的,好了,我们言归正传,开始我们的解密之旅

       动态规划的核心就是状态和转移(选择),首先,我们看这道题,它一天中可能有几种状态,它的每种状态又有几种可能,我们要根据状态去找出相对应的选择,我们是不是要穷举所有的状态,然后在根据选择去更新状态,看下列穷举的模板:

for 状态1 in 状态1的所有取值:
    for 状态2 in 状态2的所有取值:
        for ...
            dp[状态1][状态2][...] = 择优(选择1,选择2...)

每天都有3种选择:买入、卖出、无操作,我们简单的用buy、sell、none表示这三种选择

        但是这买卖还有其他条件的限制,sell必须在buy的后面,buy的前提是k>0(还可以操作的次数),none也可以分为两种状态:一种是持有股票进行,一种是没有持有股票进行,这几种情况才是比较难想的,但是想到了以后,这种题就迎难而解了

        那么我们现在这个问题的状态总共有3个,一个是天数、一个是可以操作的次数、一个是是否持有股票,我们用代码来展示一下:

        dp[i][k][0 or 1];
        0<=i<=n-1 1<=k<=K;
        n为天数,大K为交易的上限,0和1代表的是是否持有股票

然后我们根据穷举的模板就能写出得出:

   for(int i=0;i<n;i++){
        for (int k = 1; k <=K; k++) {
            for(int s=0;s<2;s++){
                dp[i][k][s]=max(buy,sell,none);
            }
        }
    }

       我们现在想要求的是dp[n-1][K][0]的值,含义就是在最后一天,最多允许K次交易,最多可以获得多少的利润

现在的穷举的框架已经给了,接下来状态进行进行转移呢?

 通过这个图我们可以很清楚的看到,每种状态是如何转移而来的,我们试着写一写状态转移方程

dp[i][k][0]=max(dp[i-1][k][0]),dp[i-1][k][1]+prices[i])
            max(  选择了无操作      选择了卖出          )

 dp[i][k][0]:我今天没有持有股票,最大的交易次数为k,可以推出昨天的情况:

  • dp[i-1][k][0]:昨天就没有持有股票,截止昨天为止最大的交易次数还是k
  • dp[i-1][k][1]+prices[i]:昨天持有股票,截止昨天最大交易数限制为k,今天进行了sell
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])
              max( 今天选择 none,         今天选择 buy        )

dp[i][k][1]:我今天持有股票,最大的交易次数为k,那么我们就可以推出昨天的情况:

  • dp[i-1][k][1]:我昨天就持有股票,截止昨天的最大交易次数为k,今天进行了none
  • dp[i-1][k-1][0]-prices[i]:我昨天没有持有,截止昨天的最大交易次数为k-1,我今天选择了buy

       现在我们已经完成了最艰难的一步了,如果之前的内容你都可以理解,恭喜你,你已经可以解决这类型问题了,看究极模板:

dp[-1][...][0] = 0
解释:因为 i 是从 0 开始的,所以 i = -1 意味着还没有开始,这时候的利润当然是 0。

dp[-1][...][1] = -infinity
解释:还没开始的时候,是不可能持有股票的。
因为我们的算法要求一个最大值,所以初始值设为一个最小值,方便取最大值。

dp[...][0][0] = 0
解释:因为 k 是从 1 开始的,所以 k = 0 意味着根本不允许交易,这时候利润当然是 0。

dp[...][0][1] = -infinity
解释:不允许交易的情况下,是不可能持有股票的。
因为我们的算法要求一个最大值,所以初始值设为一个最小值,方便取最大值。

将上图的状态转移方以及base进行总结得到:

base case:
dp[-1][...][0] = dp[...][0][0] = 0
dp[-1][...][1] = dp[...][0][1] = -infinity

状态转移方程:
dp[i][k][0] = max(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])

当数组中的k不会发生改变时,我们可以省略掉k
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

       这道题最大的操作数是2,所以k对结果的影响是不能被忽略掉的,所以我们单套模板的话,会直接超时,所以我们要对代码进行改进,穷举k的每种状态,再进行选择

   //买卖股票
    int[][] dp;
    public int maxProfit(int[] prices) {
        //对入参进行判断
        if (prices == null || prices.length == 0) {
            return 0;
        }
        //最大操作数是2
        int maxK=2;
        int n=prices.length;
        int[][][] dp=new int[n][maxK+1][2];
        for(int i=0;i<n;i++){
           //穷举k的每一种状态
          for(int k=maxK;k>=1;k--){
               //因为下面是[i-1],i是从0开始的,所以i-1=-1的情况是存在的
              if(i-1==-1){
            //处理i=0的时候的base情况
            dp[i][k][0]=0;
            dp[i][k][1]=-prices[i];
        
             continue;
           }
             //持有股票
             dp[i][k][1]=Math.max(dp[i-1][k][1],dp[i-1][k-1][0]-prices[i]);
             //无股票
             dp[i][k][0]=Math.max(dp[i-1][k][0],dp[i-1][k][1]+prices[i]);
        }
       
   
    }
     return dp[n-1][maxK][0];
}

       这道题就讲解完了,你对股票问题是否有了不一样的收获,这道题的关键还是在聪明的穷举出所有的可能的状态,基于base的基础上慢慢的向后推进,相信你有举一反三的能力,其他题也和这道题的解题方法几乎差不多,

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

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

相关文章

导入了Junit依赖,但@Test注解依然爆红~

错误描述如下所示&#xff1a; 原因&#xff1a; 解决方法&#xff0c;将<scope>test</scope>删除&#xff0c;再如下所示重新构建项目&#xff1a;

MYSQL视图和mysql触发器(学会并使用day6)

MYSQL视图和mysql触发器 MYSQL视图使用视图的原因视图作用视图规则和限制视图的应用实际操作创建表并查看创建视图视图记录修改修改视图 mysql触发器创建触发器employee表employee02表创建一个触发器t1更新语句并查看employee02表删除触发器查询触发器触发器类型OLD和NEW MYSQL…

用户体验旅程图:改进用户体验的好工具

用户体验旅程图&#xff1a;改进用户体验的好工具 怎么改进体验&#xff0c;是有方法的 用户情绪曲线来衡量用户感觉 趣讲大白话&#xff1a;没有流程刨析&#xff0c;就没法改进 【趣讲信息科技245期】 **************************** 企业管理需要基本的流程的 企业流程简称BP…

“中国网安企业出海20强” | 赛宁网安持续领航国际市场

​​8月2日&#xff0c;斯元商业咨询机构基于对网安行业长期研究数据和公开调研&#xff0c;正式发布了「China’s Top 20 Cybersecurity Tech Going Global」&#xff08;「中国网络安全企业出海20强」&#xff09;研究报告&#xff08;以下简称TOP20报告&#xff09;。 “TO…

【MYSQL】MYSQL学习笔记【基础篇】【未完待续】

文章目录 MYSQL入门一、MYSQL概述1. 数据库相关概念1.1 数据库&#xff0c;数据库管理系统与SQL1.2 数据库种类以及主流数据库管理系统排名1.3 MySQL数据库安装1.4 数据模型 二、SQL2.1 通用语法与注释2.2 SQL分类2.3 DDL2.3.1 数据库操作2.3.2 表操作2.3.2.1 表操作-查询创建2…

UIAutomator2安装及连接手机,我踩的坑都在这儿了

一、大致步骤 大家搜索网络教程&#xff0c;都会看到差不多的安装步骤&#xff1a; 1、本人使用的python3.11 2、OPPO手机 3、安装UIAutomator2&#xff1a; 在命令行中输入&#xff1a;pip install --pre uiautomator2 4、安装配置adb 安装window上&#xff08;其他的自…

excal中遇到数据变成科学计数法的处理方法

1、单元格宽度太小&#xff08;解决办法增加单元格的宽度&#xff09; 2、通过设置单元格格式里面调整 #;#;0;G/通用格式

Python毕业设计 抖音短视频数据分析与可视化 - python 大数据 可视化

文章目录 0 前言1 课题背景2 数据清洗3 数据可视化地区-用户观看时间分界线每周观看观看路径发布地点视频时长整体点赞、完播 4 进阶分析相关性分析留存率 5 深度分析客户价值判断 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕…

Python实现猫狗分类

不废话了&#xff0c;直接上代码&#xff1a; def load_imagepath_from_csv(csv_name):image_path []with open(csv_name,r) as file:csv_reader csv.reader(file)next(csv_reader)for row in csv_reader:image_path.append(row[0])return image_pathimport csv csv_name &…

如何监控制造业精密空调?看这技能就够了!

在半导体制造、电子元件生产、光学设备制造等领域&#xff0c;精密空调监控是关键的保障&#xff0c;因为微小的温度或湿度变化、微生物或颗粒物污染都可能对产品质量和性能造成巨大影响。 精密空调监控系统作为一种高度智能化的解决方案&#xff0c;能够实时监测和调节生产环境…

IIS站点无法启动,万维网发布服务无法开机启动

对于 IIS 站点无法启动和万维网发布服务无法自动启动的问题&#xff0c;你可以尝试以下的注册表设置修改&#xff1a; 1.启动类型设置&#xff1a; 打开注册表编辑器&#xff0c;导航至以下路径&#xff1a;HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Services\W3SVC 确保在右…

【参赛送好礼】2023 云原生编程挑战赛·赛道 3 赛题解析助您快速 get 参赛技能

大赛介绍 第四届云原生编程挑战赛&#xff0c;是由阿里云主办&#xff0c;云原生应用平台、天池联合承办的云原生著名品牌赛事。 自 2015 年开始&#xff0c;大赛已经成功举办了八届&#xff0c;并从 2020 年开始升级为首届云原生编程挑战赛&#xff0c;共吸引了超过 53000 支…

18、springboot默认的配置文件及导入额外配置文件

springboot默认的配置文件及导入额外配置文件 ★ Spring Boot默认加载的配置文件&#xff1a; (1) 类加载路径&#xff08;resources目录&#xff09;application.properties|yml &#xff08;相当于JAR包内&#xff09;optional: classpath:/ &#xff08;2&#xff09;类加…

中国农村程序员学习此【ES6】购买大平层,开上帕拉梅拉,迎娶白富美出任CEO走上人生巅峰

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录 比较 var 和 let 关键字的作用域--var可能被随时覆盖-全局变量for循环全局作用域函数作用域块作用域循环作用域HTML 中的全局变量提升改变一个用 const 声明的数组防止对象改变使用箭头函数编写简洁的匿名函…

aws的EC2云服务器

亚马逊官网有免费试用1年的服务器 1. 启动生成实例 1.1 创建实例时需要生成 使用的默认的 Debian 和 一个.pem后缀的秘钥 1.2 网上下一个Mobaxterm ,实例名是公有 IPv4 DNS 地址 ,使用SSH连接,登录名是admin 1.3 登录进去后 输入用户名 admin 后进去,sudo su 切换成 root…

python-爬虫作业

# -*- coding:utf-8 -*-Author: 董咚咚 contact: 2648633809qq.com Time: 2023/7/31 17:02 version: 1.0import requests import reimport xlwt from bs4 import BeautifulSoupurl "https://www.dygod.net/html/gndy/dyzz/" hd {user-Agent:Mozilla/4.0 (Windows N…

项目管理困扰?这里有个6W3H解决方案

引言 在项目管理的过程中&#xff0c;我们经常面临各种各样的挑战和问题。例如&#xff0c;如何确定项目的目标&#xff1f;如何分配资源&#xff1f;何时开始执行项目&#xff1f;在哪里进行项目&#xff1f;这些问题如果没有得到正确的解答&#xff0c;将会严重影响项目的进…

LAXCUS:私域部署的DataBricks

随着大数据技术的不断发展&#xff0c;越来越多的企业开始关注数据的价值和应用。Databricks作为一家开源的大数据平台&#xff0c;为企业提供了强大的数据分析和处理能力。然而&#xff0c;传统的Databricks部署方式存在一定的局限性&#xff0c;比如需要依赖于云服务提供商的…

go 语言实战入门案例之猜数字

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/backend-tutorial 】或者公众号【AIShareLab】回复 go 也可获取。 猜数字 第一个例子里面&#xff0c;我们会使用 Golang 来构建一个猜数字游戏。 在这个游戏里面&#xff0c;程序首先会生成一个介…

如何在群晖NAS中使用cpolar内网穿透

如何在群晖nas中使用cpolar内网穿透 文章目录 如何在群晖nas中使用cpolar内网穿透 今天&#xff0c;我们来为大家介绍&#xff0c;如何在群晖系统中&#xff0c;使用图形化界面的cpolar。 cpolar经过图形化改造后&#xff0c;使用方法已经简便了很多&#xff0c;基本与其他应用…