Leetcode贪心算法-股票专题刷题记录

 

LC上股票问题相关:

                           

 

 

总体来说,股票问题更像是动态规划而不是贪心,状态转移规则是以buy ,sell设定当前持有或不持有股票,从而计算最大利润。

六个题中主要可分为无限次买卖与有限次(III,IV)买卖两类变形,在此之上加上了冻结期、手续费等小变形。

 

  1. 基础状态转移

 

以122.买卖股票最佳时机II为例

 

 

 设置buy, sell为当前天持有或不持有股票的最大利润

则次日第i天的最大利润计算规则为:

 

 tem_sell=max(sell,buy+prices[i])
 tem_buy=max(buy,sell-prices[i])

 

翻译:如果今天持有股票,则要么没有买卖,要么买了股票(sell-prices[i])

如果今天不持有股票,则要么没有买卖,要么卖了股票(buy+prices[i])

 

最后返回sell。

 

边界处理:sell与buy的初始值,假设第0天持有股票,则buy的值应为-prices[0]。假设不持有股票,则sell为0。需要说明的是,sell与buy的意义是最大利润,也就是说如果第一天只是买了股票,没有买,则buy的值是负值,-prices[0]。没有买,利润自然为负。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices)==1:return 0

        sell,buy=0,-prices[0]

        for i in range(len(prices)):

            tem_sell=max(sell,buy+prices[i])
            tem_buy=max(buy,sell-prices[i])
            sell,buy=tem_sell,tem_buy
        return sell

 

 

2. 有限次与无限次

 初级版本:

在123,188两题中分别限定股票买卖仅可为2次与k次。相比122题,其设定为无限次。

123的题解中设定buy1,sell1,buy2,sell2分别表示当天持有或不持有第一支股票、持有或不持有第二支股票的最大利润。

状态转移方程可类推为:

 

tem_buy1 = max(buy1, -prices[i])
tem_sell1=max(sell1,buy1+prices[i])
tem_buy2=max(sell1-prices[i],buy2)
tem_sell2=max(buy2+prices[i],sell2)

 

与122题逻辑不同之处在于,buy1(持有第一支股票的最大利润),其转移方程 tem_buy1 = max(buy1, -prices[i])。含义是如果当前持有第一支股票,则要么是没有买,要么是买了(-prices[i])。

进阶版本:

188题,对比123题的2次,变成了k次,其余条件不变。那我们也可以类推,设buy1,sell1,buy2,sell2......buyk,sellk 等以此代表当前持有或不持有第i支股票的最大利润。

那么状态转移方程也可类推,除了buy1=max(buy1,-prices[i])。对于sell[i],buy[i],其状态转移方程为:

buy[i]=max(buy[i],sell[i-1]+prices[i])
sell[i]=max(sell[i],buy[i]-prices[i])

 

 思考:无限次与有限次如何实现:

在123,188题中我们能明显感到sell与buy的转移规律如下:

 

而在122,714,309中,支持无线次买卖股票,buy与sell的转移规律如图下:

 

简言之,在有限次中,buy1=max(buy1,-prices[i]),意为要么没有买卖,要么第一次买股票;

而无限次中buy=max(buy,sell-prices[i]),意为要么没有买卖,要么在没有股票的基础上买进当天的股票。而这“没有股票的基础”可以是没有买卖过股票的sell,也可以是进行过n次买卖后的sell。

 3. 冻结期、手续费等变形

309题中在122题的基础上增加冻结期这一概念,实则是在sell,buy,持有和不持有股票的基础上增加又一新状态,处于冻结期,fro.

则三者状态转移规律改为:

 

 tem_buy=max(buy,fro-prices[i])
 tem_sell=max(sell,buy+prices[i])
tem_fro=max(fro,sell)

714题在122基础上增加手续费,每笔交易需要交手续费。这个手续费其实算在buy或是sell头上都可以

状态转移规律如下:

 

tem_buy=max(buy,sell-prices[i])
tem_sell=max(sell,buy+prices[i]-fee)

申明:博客的初心是给自己写的,因为刷题复习的时候回看官方题解太累,不如自己总结专题及规律。文章默认已经看过题解,且文字跳跃性很大。毕竟自己能看懂就好,可我也不知道为啥还要给自己贴图贴代码。。。。。

 

 

 

 

 

posted @ 2022-07-04 15:00  范德麦韦  阅读(50)  评论(0)    收藏  举报