买卖股票的最佳时机
题目来源:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
题目
给定一个数组,它的第 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。
解题思路
将求差问题转换为区间和的问题。
这里采用牛顿莱布尼兹公式来侧面说明下转换的问题:
但是在这里 F() 并不是连续的,而是离散的,a 和 b 代表的是数组的下标。
在这里 F() 表示的数组称为前缀和。
前缀和:一个数组的某项下标之前(包括此项元素)的所有数组元素的和
这样,求差问题就可以转换为区间和的问题。
最大连续子数组和的问题,可以使用动态规划来求解。
dp[i]
表示以 i 结尾的最大连续子数组和,结合题意,状态转移方程为:dp[i]=max(0, dp[i-1]+diff[i])
这里 dp[i]
数组可被优化,所以上面的式子可变为:
last = max(0, last + diff[i])
其中 diff[i] = prices[i + 1] - prices[i]
,表示相隔两天股票价格的差值。所以上面的式子可进一步优化为:
last = max(0, last + prices[i + 1] - prices[i])
代码实现
class Solution:
def maxProfit(self, prices: List[int]) -> int:
last, profit = 0, 0
for i in range(len(prices) - 1):
last = max(0, last + prices[i+1] -prices[i])
profit = max(profit, last)
return profit
实现结果
参考
引用
以上就是使用数学方法,将求差转换为求区间和,解决《买卖股票的最佳时机》问题的主要内容。
欢迎关注微信公众号《书所集录》
欢迎关注微信公众号《书所集录》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。