您的位置:首页 > 其它

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

2019-01-13 22:36 477 查看

春招第一步,算法伴我行

题目描述

给定一个数组,它的第 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]


太啰嗦了,其中有个状态从头到尾就没有使用:

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]


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

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

这不嘛。

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: