[DP] 121.Best Time to Buy an Sell stock

题目描述

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 (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 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

In this case, no transaction is done, i.e. max profit = 0.


这道题归在动态规划里头,我的算法方面很薄弱,所以想了好一会儿没想出来递推方程。

就先暴力解决。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        max_profit = 0
        
        for j in range(len(prices)):
            current_price = prices[j]
            for i in range(j+1,len(prices)):
                if prices[i] > current_price :
                    temp_max_profit = prices[i] - current_price
                    if temp_max_profit > max_profit:
                        max_profit = temp_max_profit
        return max_profit

        

这个结果是没错… 但是Time Limit error了。因为给出了一个很庞大的数据。这个时间复杂度O(n^2),还是太大了。

用动态规划的思想:

a[i]数组表示,到第i个元素为止,能获得的最大利润。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        max_profit = 0
        a = [0] * len(prices)
        
        for i in range(1,len(prices)):
            min_price = min(prices[:i])
            a[i] = prices[i] - min_price
            max_profit = max(a[i],max_profit)
        return max_profit
        

这个时间复杂度达到O(n)了,但是还是Time Limit Exceded。可能是min()这个函数的复杂度比较高?

所以不用min()函数来判断。

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        
        max_profit = 0
        a = [0] * len(prices)
        if len(prices) == 0 or len(prices)==1:
            return 0
        
        else:
            min_price = prices[0] if (prices[1] - prices[0] > 0) else prices[1]
                
        for i in range(1,len(prices)):
            if prices[i] < min_price:
                min_price = prices[i]
            
            a[i] = max(prices[i] - min_price,a[i-1])
            max_profit = max(a[i],max_profit)
        
        return max_profit
这个是AC的代码。要注意的是要处理好prices长度为0和1的情况。

if len(prices) == 0 or len(prices)==1:
这一句当时我是这么写的,虽然编译没有错,但python里没有这个用法。逻辑运算里用的是or 和and
if len(prices) == 0 | len(prices)==1:
还有python的三元运算符,a = b if c else d:

min_price = prices[0] if (prices[1] - prices[0] > 0) else prices[1]

在DISCUSS里有一个人的解法特别的巧妙。我理解了一下,也用Python:

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """        
        max_profit = 0
        final_profit = 0
        for i in range(1,len(prices)):
            max_profit += prices[i]-prices[i-1]
            max_profit = max(0,max_profit)
            final_profit = max(max_profit,final_profit)      
        return final_profit

这个解法都不需要考虑数组是0和1的情况。而且也是O(n)的时间复杂度,解释一下:

 假设数组为[a,b,c,d,e,f,g],max_profit实的计算:

当i = 1:max_profit = b - a

当i = 2:(b - a) + (c - b) = c - a

当i = 3 :(b - a) + (c - b) + (d - c) = d - a

...

这是在开始默认price[0]为最小值,计算当前i与默认最小值的差值。

这一行,假如b - a < 0 也就是 b < a ,max_profit 置0,其实作用就是确定当前的最小值。

max_profit = max(0,max_profit)

 也就是说,在接下来max_profit的累加中,b成为了最小值,计算

 当i = 2 :(b - a)+ (c - b) = c - b

 当i = 3(b - a) + (c - b) + (d - c) = d - b

 max_profit存储的是当前i位置的价格与当前的最低价格的差值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值