⛅(day17)
目录
🖍题目:
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。返回 你能获得的 最大 利润 。(1 <= prices.length <= 3 * 104)
🌠示例 1:
输入: prices = [7,1,5,3,6,4]
输出: 7
说明: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。最大利益 = 4 + 3 = 7
🌠示例 2:
输入: prices = [1,2,3,4,5]
输出: 4
说明: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
(注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,不满足最多只能持有一股股票的要求,你必须在再次购买前出售掉之前的股票。)最大利益 = 4
🌠示例 3:
输入: prices = [7,6,4,3,1]
输出: 0
说明: 在这种情况下, 没有交易完成, 所以最大利润为 0。(这里要求利润不能为负数)
题目分析:
题目要求在只能持有一股股票的情况下,进行购进和抛售,使得获取最大利益。可以在同一天买入和抛售,因为当天买卖股票的价格不变,所以这一天买卖股票的利益 = 0
以例1prices = [6,1,3,5]为例,最大利益 =(5-1)= 4,有很多人可能会想,我怎么知道要在第二天买入股票右在第四天卖出?实际上这会把问题复杂化。且看,换另一种计算方法 最大利益=(3-1)+(5-3)= 4.那么就有,我们只需要比较后一天的股票售价和前一天的股票售价,如果后一天的股票售价较高就可以出售。这就是贪婪算法。
解题思路:
解法一(贪婪算法)
根据贪婪算法(又叫贪心算法),我们只需比较后一天的股票售价和前一天的股票售价,如果后一天的股票售价较高就可以出售,出售获得的 利润=后一天股价 - 前一天股价
解法二(动态规划化)
上动态规划五部曲
✨1.分析确定dp数组以及其下标的含义
创建二维列表dp = [[0, 0], [0, 0]........[0, 0]]
为什么不创建一维列表?
因为我i们要表示两个状态:dp[i][0]表示第i天不持有股票,dp[i][1]b表示持有股票
✨2.确定递推公式
根据上两个状态
1.第i天持有股票(dp[i][1])
那么可能的结果有:(1)第i-1天也持有股票,(2)第i-1天买入
prices[i]为股价
那么第i天持有股票得到得利润为
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
2.第i天不持有股票(dp[i][0])
那么可能的结果有:(1)第i-1天不持有股票,(2)第i-1天抛售
那么第i天持有股票得到得利润为
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])那为什么第i天第状态不去判断今天买入或者抛售?
因为第i天买入抛售的结果已经包含在持不持有股票中。
最后不持有股票得状态即为本题的解(没抛售股票获得的利润一定小于抛售后)
✨3.如何初始化dp数组
由公式可知,dp[i][0], dp[i][1],是以dp[0][0], dp[0][1],为基础的
那么dp[0][0] = 0,(因为不持有股票)
dp[0][1] = - prices[0],(因为购入了股票)
✨4.确定遍历的顺序
显然,dp[i][x]的递推方式为顺推
✨5.举例验证推导的dp数组(公式)是否正确
可以以例1为例检验
代码实现
🌈贪婪算法
def maxProfit(prices):
ans = 0
for i in range(1, len(prices)):
if prices[i] > prices[i - 1]:
ans += prices[i] - prices[i - 1]
return ans
✏代码注释
def maxProfit(prices):
ans = 0 # 初始化利润
for i in range(1, len(prices)): # 由于prices[i-1]的限制,i从1开始。
if prices[i] > prices[i - 1]: # 比较前一天股价和后一天股价
ans += prices[i] - prices[i - 1] # 计算获得的利润
return ans # 返回结果
🌈动态规划解法
def maxProfit(prices):
dp = [[0] * 2 for _ in range(len(prices))]
dp[0][0] = 0
dp[0][1] = - prices[0]
for i in range(1, len(prices)):
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i])
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
return dp[len(prices) - 1][0]
✏代码注释
def maxProfit(prices):
dp = [[0] * 2 for _ in range(len(prices))] # 创建二维数组用于储存持有或不持由股票时的利润
dp[0][0] = 0 # 初始化公式基础
dp[0][1] = - prices[0]
for i in range(1, len(prices)): # 由于dp[i-1]的限制,i从1开始
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]) # 用max()取持有或不持由股票时利润最大值
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i])
return dp[len(prices) - 1][0] # 返回最终不持由股票的状态
今天就到这,明天见。🚀
❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄