题目描述
给定一个数组,它的第 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。
分析
求最大利润,即求数组中最大差值,但是这个差值要满足一个条件,即小的值在前面,大的值在后面,即 min_index < max_index
解法一:暴力法
根据之前分析,我们可以对这个数组进行遍历,当遍历到某个元素时,再对该元素后面的值遍历,然后求差值,和暂存起来的最大值比较。这个解法比较简单,但是时间复杂度较高,为O(n^2)
def maxProfit(prices: list) -> int:
_max = 0 # 初始化一个变量用来存储最大差值
for i, e in enumerate(prices):
for k in prices[i+1:]:
# 和当前最大值比较
_max = max(k - e, _max)
return _max
解法二:记录最小值,同时计算最大差值
解法一的做法是,第一次遍历得到的值作为买入点,然后对之后的值做第二次遍历,找出卖出点。
其实我们遍历一次可以搞定,每次遍历时,把当前股价当做卖点,那么要获取最大利润,肯定要在当天之前的历史最低点买入,而这个历史最低点,我们每次遍历时可以存起来。这样我们每次遍历都会得到当天卖出时的最大利润,然后再和历史最大利润相比,就可以得到结果了。
代码如下:
def maxProfit(prices: List[int]) -> int:
_max = 0 # 初始化一个变量用来存储最大差值
min_price = float('inf') # 定义一个无穷大的浮点数
for p in prices:
# 减去历史最小值,和当前最大利润(差值)比较
_max = max(p - min_price, _max)
# 目的是记录历史最小值
min_price = min(min_price, p)
return _max