leetcode股票问题方法收集转载自微信公众号labuladongSweetCloud

而这里,我们不用递归思想进行穷举,而是利用「状态」进行穷举。我们具体到每一天,看看总共有几种可能的「状态」,再找出每个「状态」对应的「选择」。我们要穷举所有「状态」,穷举的目的是根据对应的「选择」更新状态。听起来抽象,你只要记住「状态」和「选择」两个词就行,下面实操一下就很容易明白了。

for状态1in状态1的所有取值:for状态2in状态2的所有取值:for...dp[状态1][状态2][...]=择优(选择1,选择2...)比如说这个问题,每天都有三种「选择」:买入、卖出、无操作,我们用buy,sell,rest表示这三种选择。但问题是,并不是每天都可以任意选择这三种选择的,因为sell必须在buy之后,buy必须在sell之后。那么rest操作还应该分两种状态,一种是buy之后的rest(持有了股票),一种是sell之后的rest(没有持有股票)。而且别忘了,我们还有交易次数k的限制,就是说你buy还只能在k>0的前提下操作。

很复杂对吧,不要怕,我们现在的目的只是穷举,你有再多的状态,老夫要做的就是一把梭全部列举出来。这个问题的「状态」有三个,第一个是天数,第二个是允许交易的最大次数,第三个是当前的持有状态(即之前说的rest的状态,我们不妨用1表示持有,0表示没有持有)。然后我们用一个三维数组就可以装下这几种状态的全部组合:

dp[i][k][0or1]0<=i<=n-1,1<=k<=Kn为天数,大K为最多交易数此问题共n×K×2种状态,全部穷举就能搞定。

for0<=i

我们想求的最终答案是dp[n-1][K][0],即最后一天,最多允许K次交易,最多获得多少利润。读者可能问为什么不是dp[n-1][K][1]?因为[1]代表手上还持有股票,[0]表示手上的股票已经卖出去了,很显然后者得到的利润一定大于前者。

记住如何解释「状态」,一旦你觉得哪里不好理解,把它翻译成自然语言就容易理解了。

二、状态转移框架现在,我们完成了「状态」的穷举,我们开始思考每种「状态」有哪些「选择」,应该如何更新「状态」。只看「持有状态」,可以画个状态转移图。

通过这个图可以很清楚地看到,每种状态(0和1)是如何转移而来的。根据这个图,我们来写一下状态转移方程:

dp[i][k][0]=max(dp[i-1][k][0],dp[i-1][k][1]+prices[i])max(选择rest,选择sell)

解释:今天我没有持有股票,有两种可能:要么是我昨天就没有持有,然后今天选择rest,所以我今天还是没有持有;要么是我昨天持有股票,但是今天我sell了,所以我今天没有持有股票了。

dp[i][k][1]=max(dp[i-1][k][1],dp[i-1][k-1][0]-prices[i])max(选择rest,选择buy)

解释:今天我持有着股票,有两种可能:要么我昨天就持有着股票,然后今天选择rest,所以我今天还持有着股票;要么我昨天本没有持有,但今天我选择buy,所以今天我就持有股票了。这个解释应该很清楚了,如果buy,就要从利润中减去prices[i],如果sell,就要给利润增加prices[i]。今天的最大利润就是这两种可能选择中较大的那个。而且注意k的限制,我们在选择buy的时候,把k减小了1,很好理解吧,当然你也可以在sell的时候减1,一样的。

现在,我们已经完成了动态规划中最困难的一步:状态转移方程。如果之前的内容你都可以理解,那么你已经可以秒杀所有问题了,只要套这个框架就行了。不过还差最后一点点,就是定义basecase,即最简单的情况。

dp[-1][k][0]=0解释:因为i是从0开始的,所以i=-1意味着还没有开始,这时候的利润当然是0。dp[-1][k][1]=-infinity解释:还没开始的时候,是不可能持有股票的,用负无穷表示这种不可能。dp[i][0][0]=0解释:因为k是从1开始的,所以k=0意味着根本不允许交易,这时候利润当然是0。dp[i][0][1]=-infinity解释:不允许交易的情况下,是不可能持有股票的,用负无穷表示这种不可能。把上面的状态转移方程总结一下:

basecase:dp[-1][k][0]=dp[i][0][0]=0dp[-1][k][1]=dp[i][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])读者可能会问,这个数组索引是-1怎么编程表示出来呢,负无穷怎么表示呢?这都是细节问题,有很多方法实现。现在完整的框架已经完成,下面开始具体化。

三、秒杀题目第一题,k=1

直接套状态转移方程,根据basecase,可以做一些化简:

dp[i][1][0]=max(dp[i-1][1][0],dp[i-1][1][1]+prices[i])dp[i][1][1]=max(dp[i-1][1][1],dp[i-1][0][0]-prices[i])=max(dp[i-1][1][1],-prices[i])解释:k=0的basecase,所以dp[i-1][0][0]=0。

现在发现k都是1,不会改变,即k对状态转移已经没有影响了。可以进行进一步化简去掉所有k:dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i])dp[i][1]=max(dp[i-1][1],-prices[i])直接写出代码:

intn=prices.length;int[][]dp=newint[n][2];for(inti=0;i

for(inti=0;i

//k==1intmaxProfit_k_1(int[]prices){intn=prices.length;//basecase:dp[-1][0]=0,dp[-1][1]=-infinityintdp_i_0=0,dp_i_1=Integer.MIN_VALUE;for(inti=0;i

第二题,k=+infinity

如果k为正无穷,那么就可以认为k和k-1是一样的。可以这样改写框架:

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])=max(dp[i-1][k][1],dp[i-1][k][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])直接翻译成代码:

intmaxProfit_k_inf(int[]prices){intn=prices.length;intdp_i_0=0,dp_i_1=Integer.MIN_VALUE;for(inti=0;i

每次sell之后要等一天才能继续交易。只要把这个特点融入上一题的状态转移方程即可:

dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i])dp[i][1]=max(dp[i-1][1],dp[i-2][0]-prices[i])解释:第i天选择buy的时候,要从i-2的状态转移,而不是i-1。翻译成代码:

intmaxProfit_with_cool(int[]prices){intn=prices.length;intdp_i_0=0,dp_i_1=Integer.MIN_VALUE;intdp_pre_0=0;//代表dp[i-2][0]for(inti=0;i

每次交易要支付手续费,只要把手续费从利润中减去即可。改写方程:

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]-fee)解释:相当于买入股票的价格升高了。在第一个式子里减也是一样的,相当于卖出股票的价格减小了。直接翻译成代码:

intmaxProfit_with_fee(int[]prices,intfee){intn=prices.length;intdp_i_0=0,dp_i_1=Integer.MIN_VALUE;for(inti=0;i

k=2和前面题目的情况稍微不同,因为上面的情况都和k的关系不太大。要么k是正无穷,状态转移和k没关系了;要么k=1,跟k=0这个basecase挨得近,最后也没有存在感。

这道题k=2和后面要讲的k是任意正整数的情况中,对k的处理就凸显出来了。我们直接写代码,边写边分析原因。

原始的动态转移方程,没有可化简的地方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])按照之前的代码,我们可能想当然这样写代码(错误的):

intk=2;int[][][]dp=newint[n][k+1][2];for(inti=0;i

还记得前面总结的「穷举框架」吗?就是说我们必须穷举所有状态。其实我们之前的解法,都在穷举所有状态,只是之前的题目中k都被化简掉了。这道题由于没有消掉k的影响,所以必须要对k进行穷举:

intmax_k=2;int[][][]dp=newint[n][max_k+1][2];for(inti=0;i=1;k--){if(i-1==-1){/*处理basecase*/}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]);}}//穷举了n×max_k×2个状态,正确。returndp[n-1][max_k][0];如果你不理解,可以返回第一点「穷举框架」重新阅读体会一下。

这里k取值范围比较小,所以可以不用for循环,直接把k=1和2的情况手动列举出来也可以:

dp[i][2][0]=max(dp[i-1][2][0],dp[i-1][2][1]+prices[i])dp[i][2][1]=max(dp[i-1][2][1],dp[i-1][1][0]-prices[i])dp[i][1][0]=max(dp[i-1][1][0],dp[i-1][1][1]+prices[i])dp[i][1][1]=max(dp[i-1][1][1],-prices[i])

intmaxProfit_k_2(int[]prices){intdp_i10=0,dp_i11=Integer.MIN_VALUE;intdp_i20=0,dp_i21=Integer.MIN_VALUE;for(intprice:prices){dp_i20=Math.max(dp_i20,dp_i21+price);dp_i21=Math.max(dp_i21,dp_i10-price);dp_i10=Math.max(dp_i10,dp_i11+price);dp_i11=Math.max(dp_i11,-price);}returndp_i20;}有状态转移方程和含义明确的变量名指导,相信你很容易看懂。其实我们可以故弄玄虚,把上述四个变量换成a,b,c,d。这样当别人看到你的代码时就会一头雾水,大惊失色,不得不对你肃然起敬。

第六题,k=anyinteger

有了上一题k=2的铺垫,这题应该和上一题的第一个解法没啥区别。但是出现了一个超内存的错误,原来是传入的k值会非常大,dp数组太大了。现在想想,交易次数k最多有多大呢?

一次交易由买入和卖出构成,至少需要两天。所以说有效的限制k应该不超过n/2,如果超过,就没有约束作用了,相当于k=+infinity。这种情况是之前解决过的。

直接把之前的代码重用:

intmaxProfit_k_any(intmax_k,int[]prices){intn=prices.length;if(max_k>n/2)returnmaxProfit_k_inf(prices);

int[][][]dp=newint[n][max_k+1][2];for(inti=0;i=1;k--){if(i-1==-1){/*处理basecase*/}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]);}returndp[n-1][max_k][0];}至此,6道题目通过一个状态转移方程全部解决。

四、最后总结本文给大家讲了如何通过状态转移的方法解决复杂的问题,用一个状态转移方程秒杀了6道股票买卖问题,现在想想,其实也不算难对吧?这已经属于动态规划问题中较困难的了。

关键就在于列举出所有可能的「状态」,然后想想怎么穷举更新这些「状态」。一般用一个多维dp数组储存这些状态,从basecase开始向后推进,推进到最后的状态,就是我们想要的答案。想想这个过程,你是不是有点理解「动态规划」这个名词的意义了呢?

具体到股票买卖问题,我们发现了三个状态,使用了一个三维数组,无非还是穷举+更新,不过我们可以说的高大上一点,这叫「三维DP」,怕不怕?这个大实话一说,立刻显得你高人一等,名利双收有没有。

所以,大家不要被各种高大上的名词吓到,再多的困难问题,奇技淫巧,也不过是基本套路的不断升级组合产生的。只要把住算法的底层原理,即可举一反三,逐个击破。

THE END
1.公众号股票金融小程序排行榜2024年11月17日日榜单日榜 周榜 月榜 排行小程序简介涉及文章篇数曝光量对应公众数操作 1 中证金牛座 16 343255 1 详情 2 东方财富一股票行情财经资讯股吧 东方财富旗下集行情查看,股吧交流,资讯浏览为一体的综合类股票小程序。 6 185737 3 详情 3 雪球丨基金股票交流交易平台 千万人在用的股票投资应用,近距离感受投资高手对于...https://data.xiguaji.com/MiniAppRank/25/1/20241117.html
2.公众号排行榜(日、周、月)前往榜单 ?2024 NEWRANK 指数榜 公众号榜单 每日必看榜单 视频号 小红书 抖音 快手 哔哩哔哩 微博 更多 涨粉榜 话题榜 飙升榜 营销案例周榜 达人投放指数榜 AI新榜 专注观察AI产业新趋势 商业种草榜 多行业各品牌投放数据 新榜榜单权威的新媒体影响力排行榜 前往体验 榜单解读自定义榜单账号收录...https://www.newrank.cn/ranklist/gongzhonghao?l=sq_main-t_xbbd
3.2018年十大财经股票微信公众号排行榜TOP9每日经济新闻 最有价值股票投资类微信公众号,海量免费内参,一览三大证券报精华内容、私募精华传闻、最强复盘分析,助您驾驭股海沉浮。 TOP10同花顺财经 多年来股票频道潜心深耕资本市场,为用户提供最及时最准确的投资资讯,呈现最权威最全面的专家视点,搭建最透明最实用的维权平台。http://www.360doc.com/content/18/0523/15/26470171_756392357.shtml
4.财经网站大全财经微信公众号云掌财经网站导航为您提供权威的财经网站排行和财经微信公众号排行榜,云掌财经网站导航致力于为投资理财用户呈现更权威的财经网站。http://hao.123.com.cn/
5.股票微信排名推荐,股票公众号大全股市资讯、牛股推荐、个股诊断、选股技巧、解套指导、行情预测,一站式服务。 欢迎一起交流,一起赚钱,一起咸鱼翻身。 权威机构认证,股票微信公众号推荐榜,排名第一实时发布股票行情,预测大盘走势,每天都有推送牛股。还有专业从事股票行业10年以上的老师给你做个股分析。https://m.sohu.com/a/114294763_384999
6.不只搜全网还打通微信公众号腾讯重磅推出AI搜索这款产品不仅具备搜索功能,还能回答问题、创作文字和生成图片。作为腾讯旗下的产品,ima在搜索答案时,除了全网信源外,还整合了微信公众号文章的生态资源。这意味着用户可以获取整个公众号世界中的优质知识,从而获得更好的答案和高质量的相关信息,有效提升信息获取效率。http://www.3djulebu.com/wap/bencandy.php?fid=64&id=279493
7.有股的大家一起个个股吧宣传,快手,微信公众号,抖音让老师们一起大...炒股第一步,先开个股票账户 有股的大家一起个个股吧宣传,快手,微信公众号,抖音让老师们一起大面积宣传,今天这么好的大盘都落后大盘了,st概念,看st都涨多少了,它落后了,微盘股概念,盘子小不到4亿盘子,举牌概念,大股东才7%股份,如果今年不退市还有重整概念,资不抵债被重整,看着便宜啊,融资买满仓干,加仓加仓一...https://caifuhao.eastmoney.com/news/20241120225456465030940
8.广和通:具体以公司微信公众号或官网资讯为准股票频道公司微信公众号发布信息:广和通一一具身智能机器人开发平台Fibot入选中国信通院“人工智能 电信业”赋智先锋案例24年9月26日,在中国国际信息通信展(简称“PT展”)分论坛“信息通信行业智能化变革论坛”上,中国信通院与《通信产业网》联合公布了2024年“人工智能 电信业”领航先锋案例。广和通具身智能机器人开发平台Fi...https://stock.stockstar.com/IG2024112200007515.shtml
9.2024年陕西西安交通大学钱学森学院招聘历年高频考题难易错点...2014年6月9日起,微信公众平台开始采用技术加人工举报的方式对“集赞”行为进行全平台清理和规范。对于违反微信用户协议和公众平台用户协议的公众号,微信出台了详细处理机制:发现一次集赞行为、封号7天,累计发现二次、封号15天,累计三次封号30天,均不可提前解封;累计发现四次,永久封号,不可解封。 这段文字的主要...https://max.book118.com/html/2024/0501/6033211240010123.shtm
10.黄金网首页 财经 股票 行情 数据 基金 黄金 外汇 期货 理财 原创 汽车 视频 路演 博客 名家热力榜 财经号 7*24快讯 金市直播 名家机构 要闻 行情 数据中心 实物黄金 博客 视频 名家热力榜 行业 新手学堂 财经日历 查询 16:02:16 北约秘书长吕特周五在佛罗里达州会见了当选美国总统特朗普。 16:00:50...http://gold.cnfol.com/
11.运营笔试练习知识点总结11、逃离北上广、丢书大作战、凌晨四点半的直播都与公众号“新世相”有关 12、温婉、代古拉k和高火火等网络红人发迹于抖音平台 13、科技类自媒体像差评和虎嗅网;视频自媒体像papi酱、野食小哥、办公室小野和陈翔六点半等 14、最常用的微信公众号第三方数据排行统计工具有新榜;最常用的微信公众号第三方内容编辑排版...https://www.jianshu.com/p/ddd1360f476d
1.值得关注的财经类公众号这三个公众号算是非常知名的财经类公众号,这些年也算是做的非常好的了,内容全面系统的整合性报道,切中新闻热点。 4、金融八卦女。 这位金融八卦女是一位基金行业的从业人员,她开设的金融八卦女微信公众号是金融业内最有名气的自媒体平台之一,据说绝大多数的金融从业者都关注了这个微信公众号。 https://www.31344.com/meirituijian/26257.html
2.剧变!车企销量TOP10,中国品牌首次占比过半,多家上市车企在列2023年,凭借新能源车的优异表现,以及海外市场的强势拉动,成功重返两榜。以年累计批发102.8万辆的成绩,排名2023年乘用车批发销量排行榜第7,同比增长16.7%。 「图片来源:长城汽车微信公众号」 其中,新能源乘用车销量为26.2万辆,同比增长超90%,并且占到年批发销量的25.39%。另外,作为中国汽车工业最早“走出去”的品牌...https://www.yoojia.com/article/9443959688867197867.html
3.股票个人公众号排名榜,2018十大优质股票投资类微信公众号推荐最有价值股票投资类微信公众号,海量免费内参,一览三大证券报精华内容、私募精华传闻、最强复盘分析,助您驾驭股海沉浮。 TOP10同花顺财经 多年来股票频道潜心深耕资本市场,为用户提供最及时最准确的投资资讯,呈现最权威最全面的专家视点,搭建最透明最实用的维权平台。https://www.douban.com/note/695852018/
4.关注公众号就能被拉入“炒股群”?企业微信被“杀猪盘”用的炉火...企业微信被“杀猪盘”用的炉火纯青 你是否记得这样一条新闻:“‘炒股群’里除了自己全是骗子”。 笔者不光记得,而且遇到了,还是两次。 这两次经历有一个共同点:笔者都在关注陌生公众号后,直接“加入企业”,成为了“企业成员”,随后被拉入“炒股群”,而两个企业本身的经营范围与证券毫无关联,分别以:商贸和教育...https://tech.hexun.com/2021-12-21/204978684.html
5.是这样的,我是一个微信公众号号主,写一些股票分析方面的文章,然后我...这个不涉及直接代炒股,初步看没有刑事风险 https://www.66law.cn/question/34835768.aspx
6.香港探索生涯国际教育微信公众号[引用日期2023-06-02] 6. 香港中国地情网[引用日期2023-06-02] 7. 周末地理|东方之珠——香港河北经贸大学旅游学院微信公众号[引用日期2023-06-04] 8. GDP(现价美元) - Hong Kong SAR, China世界银行[引用日期2021-10-10] 9. 人均GDP(现价美元) - Hong Kong SAR, China世界...https://baike.sogou.com/v53669.htm
7....建炒股群收会员费卖荐股软件合作分成微信公众号荐股骗术...微信公众平台近日发布公告称,即日起微信公众平台将配合微信安全中心,针对通过推荐股票、期货等“非固定收益类投资产品”,实施诈骗、骚扰行为的信息和公众号进行处理。微信安全中心提醒,此类“荐股”欺诈,往往利用用户的想盈利心理“空手套白狼”,推荐完全凭运气,股票涨了就跟着分红或收费),股票跌了,也不负任何责任。 https://paper.hebiw.com/epaper/hbrb/2018/01/10/RB05/story/2349528.shtml
8.诚筑说北京java培训微信公众号有订阅号、服务号、企业微信号三类,可根据自己实际应用场景注册对应的类型即可,在开发中我们可以使用微信公众平台测试号进行开发测试。但是,在开发之前一定要确定项目实际所运行的账号类型,因为这牵扯到官方的接口权限问题。针对不同的权限,在开发之前我们需要根据业务场景及接口权限设计好对应场景实现的解决方案...https://www.chengzhushuo.com/course_java.html
9.舟山市事业单位2014年招聘信息1、请长按红色复制公务员考试信息网公众号,也可以点击右侧的按钮点击复制。 2、在微信公众号搜索并关注官方公众号。 3、回复大礼包,获得30G公务员、事业单位、教师(视频、真题、题库、教材等)资料! 1 . 抗日战争时期,无产阶级及其政党在革命统一战线中必须坚持的原则是( ) ...http://m.sdsgwy.com/article/html/247861.html