leetcode 121. Best Time to Buy and Sell Stock 动态规划 python3

一.问题描述

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
             Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

二.解决思路

这道题就是找两个点,右边的点减左边的点差值最大,此时右边的点的右边不存在比该点还大的值,左边点的左边不存在比该值还小的值。

动态规划:

既然知道了是要找这样的两个点,那么对于当前迭代到的位置,最大收益是result。

思考之后什么情况下,这个result会被更改。

1.右边出现了比当前最大值更大的值。

2.右边出现了比当前更小的值,并且之后的某个值(可能比最大值小)减去这个更小的值比result更大。

然后对应与对于每次新迭代的位置:

如果当前这个值减去之前的最小值比result大,更新result,把最大值设置为当前值(能同时满足1,2,对于1来说,如果比当前最大值大,那么减去之前的最小值一定比result大)。

如果当前值比之前的最小值小,更新最小值以备之后用来判断2.

时间复杂度O(N),空间复杂度O(1)

这种实现可能不那么动态规划,虽然可能好理解一点。因为动态规划不就是查表嘛

比较动态规划的就是设置一个profit数组保存知道当前迭代的最大profit

更新方法: profit[i]=max(profit[i-1],prices[i]-min_price),

但是入之前2提到的,我们必须持续更新min_price,

之后判断当前值与min_price哪个更小。

时间复杂度:O(N),空间复杂度:O(N)

PS:这道题还有一道进阶题,其实也很简单:leetcode 122. Best Time to Buy and Sell Stock II

更多leetcode算法题解法: 专栏 leetcode算法从零到结束

三.源码

1.不那么动态规划,可能更好理解一点

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:return 0
        res,min_price,max_price=0,prices[0],prices[0]
        for price in prices:
            if price-min_price>res:
                max_price=price
                res=max_price-min_price
            if price<min_price:
                min_price=price
        return res

2.动态规划

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if not prices:return 0
        len_prices=len(prices)
        profits,min_price=[0]*len_prices,prices[0]
        for i in range(1,len_prices):
            profits[i]=max(profits[i-1],prices[i]-min_price)
            min_price=min(min_price,prices[i])
        return profits[len_prices-1]

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值