您的位置:首页 > 其它

LeetCode每日一题--买卖股票的最佳时机

2020-03-15 18:21 169 查看

  【前言】坚持日更LeetCode刷题系列

    不积跬步,无以至千里;不积小流,无以成江海。愿与诸君共勉!


  【题目】121.买卖股票的最佳时机

    题目描述:给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

            如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

            注意你不能在买入股票前卖出股票。


    示例:

示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

    

思路一:
我们很容易想到暴力求解的方法,即用两层循环对列表进行遍历,每次找到比当前最大利润大的值,则将其赋值给它,否则继续循环。具体代码如下:

class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
if len(prices)==0 or len(prices)==1:
return 0
else:
profit_max = 0
for i in range(len(prices)-1): #从第一天遍历到倒数第二天
for j in range(i,len(prices)): #从第i天遍历到最后一天
if prices[j]-prices[i] > profit_max: #如果得到更高的利润,则将其赋值给profit_max
profit_max = prices[j]-prices[i]
return profit_max

    运行结果:出现了

超时
错误,显然采用两层循环的方式,时间复杂度为O(n^2),因此对于过长的列表时,会出现超时的现象。


    

思路二:
那么我们怎么优化呢???先不急,我们先思考下我们在上一个思路中为什么要循环两次呢?因为是要得到最高的利润,那么我们在上面从第二个循环中从第i天遍历到最后一天则是为了寻找到卖出股票的最佳时机,那么不难推测第一个循环则是为了得到最佳的买入时间。那么请接着往下思考,如果我们每次都
记录下买入的最低价格
,与当前价格作比较,选择出到底是第i天买入还是记录的价格日买入,那么循环的次数一次即可解决问题。具体内容如下:

class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
min_price = float("inf")  #初始化最低买入价格
max_profit = 0  #初始化最大利润
for i in range(len(prices)):
if prices[i] < min_price:  #记录历史最低价
min_price = prices[i]
if prices[i]-min_price > max_profit:  #记录最大利润
max_profit = prices[i] - min_price
return max_profit

    运行结果:
    

    

思路三:
我们再次转化下思路,如果我们将所有的当天与前一天价格的差值算出来,例如:股票原本价格[7,1,5,3,6,3],那么差值为[-6,4,-2,3,-2],因为里面的数值代表着收益与亏损的情况,因此我们算出
连续子数和的最大值即可得到最大利润
。最大连续子序和可参考我的这篇文章


    关于其中一些知识的链接:
    算法题解


    分享就到这里了,欢迎大家一起交流讨论。


    

注明

    题目来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock

  • 点赞 2
  • 收藏
  • 分享
  • 文章举报
Mingw_ 发布了36 篇原创文章 · 获赞 64 · 访问量 2771 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: