基础算法之买卖股票最佳时机(Leetcode-121)

春招第一步,算法伴我行

题目描述

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
如:[7,1,5,3,6,4],最大利润为6-1=5.

思路

动态规划题目。
当前状态是什么?上一状态和当前状态有什么关系?怎么由上一状态推出当前状态?从这三个方面来回答。

  1. 当前状态:
    肯定是我当前的股票价格对应的利润。一个变量表示状态够吗?不够。。。为什么不够呢?由于只能进行一次买卖,因此设计到你是否使用当前的股票之前,你到底还能不能进行交易。因此还需要开辟一个变量来进行状态的二维定义:对于当前的股票,我所对应的状态是否允许我再进行操作。
    思考一下:我所对应的状态有哪些?由于只能进行一次交易,自然能想到:可以交易、不能交易两种状态。但是我们引申一下(其实两种状态已经足够,待会分析),可以交易是什么意思?是还没进行一次的前提下可以买入?还是已经买入只能卖出??因此状态有三个:当前股票下,我还没有进行任何操作dp[i][0],我可以买入:dp[i][1],我已经买入,只能卖出了dp[i][2]三种状态。
  2. 上一状态
    当前状态和上一状态是一样的。只不过需要注意最初是状态:dp[0][0]=0, dp[0][1]=-nums[0], dp[0][2]=0
  3. 上一状态和当前状态有嘛关系
    还是从当前的三个状态来看:dp[i][0]:一次操作都没进行所对应的最大利润,当然,上一状态也是什么都没进行,两个状态是一样的:dp[i][0]=dp[i-1][0]dp[i][1]:已经买进股票对应的最大利润,上一状态有两种可能:dp[i-1][0]:即我上一状态什么都没做,那自然是第i次进行了买入,利润为dp[i-1][0]+prices[i]dp[i-1][1]:第i-1次已经买入,第i次什么都没做,对应的利润是dp[i-1][1],因此,dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i](考虑了股票价可能为负);dp[i][2]:和dp[i][1]类似,dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i]

代码

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:return 0
        dp = [[0]*3 for _ in range(len(prices))]
        dp[0][0], dp[0][1], dp[0][2] = 0, -prices[0], 0
        for i in range(1, len(prices)):
            dp[i][0] = dp[i-1][0]
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
            dp[i][2] = max(dp[i-1][2], dp[i-1][1]+prices[i])
        return dp[-1][2]

AC
太啰嗦了,其中有个状态从头到尾就没有使用:dp[i][0]==0,简化一下:

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:return 0
        dp = [[0]*2 for _ in range(len(prices))]
        dp[0][0], dp[0][1] = -prices[0], 0
        for i in range(1, len(prices)):
            dp[i][0] = max(dp[i-1][0], 0-prices[i])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
        return dp[-1][1]

AC
其实有个很简单的思路去解决:两个变量:最低价格和最大利润。从头遍历,先计算利润,只要是最大,更新最大利润。如果当前价格是最低价格,更新最低价格。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        if not prices:return 0
        buy_price, profit = prices[0], 0
        for x in prices[1:]:
            if x<buy_price:
                buy_price = x
            if x-buy_price>profit:
                profit = x-buy_price
        return profit

AC

这不嘛。

干干巴巴的,麻麻赖赖的,一点都不圆润,盘他!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值