121. 买卖股票的最佳时机
1.题目
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
2.实现
法一:
鉴于股票题经常考虑差价,所以观察相邻差的数组可发现,如何去记录当前状态值和更新利润最大值
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n == 1:
return 0
diff = []
for i in range(1, n):
diff.append(prices[i] - prices[i - 1])
res = -inf
tmp = 0
for u in diff:
if u <= (u + tmp):
tmp = u + tmp
else:
tmp = u
res = max(res, tmp)
return res if res > 0 else 0
法二:
动态规划,难点在于如何定义dp数组以及推导递推公式
class Solution:
def maxProfit(self, prices: List[int]) -> int:
# 用动态规划dp做,且只需长度为2的数组记录
dp = [0] * 2
dp[0] = -prices[0] # 表示持有股票(不一定是当前的)获得的最大金额
dp[1] = 0 # 表示不持有股票获得的最大金额
for u in prices:
dp[0] = max(dp[0], -u)
dp[1] = max(dp[1], u + dp[0])
return dp[1]
法三:
贪心算法,时间复杂度O(n),拓展做做
122.买卖股票的最佳时机II
1.题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
2.实现
如何理解买卖多次!——唯一受影响的即递推公式——对于持有股票和不持有股票两种情景来说,持有股票由于可以多次卖出,所以应当改变;未持有股票是否记录了最大利润,可以自己举例理解
class Solution:
def maxProfit(self, prices: List[int]) -> int:
# 贪心算法即求所有的正值
# 动规思考如何体现可以多次买卖,即持有股票时欲购买新股票,则需考虑遗留的利润
# 未持有则记录到该索引位置能获得的最大利润,一旦重新购入有剩余利润的股票并高价卖出时则未持有对应的dp[1]更新
dp = []
dp.append(-prices[0])
dp.append(0)
for u in prices:
dp[0] = max(dp[0], dp[1] - u)
dp[1] = max(dp[1], dp[0] + u)
return dp[1]