121. 买卖股票的最佳时机
# 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
# 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
# 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
#
# 示例 1:
# 输入:[7,1,5,3,6,4]
# 输出:5
# 解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
# 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
#
# 示例 2:
# 输入:prices = [7,6,4,3,1]
# 输出:0
# 解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
class Solution:
# 1. 确定dp数组(dp table)以及下标的含义
# dp[i][0]表示第i天持有股票所得最多现金
# dp[i][1]表示第i天不持有股票所得最多现金
def maxProfit(self, prices: [int]) -> int:
if len(prices) == 1:
return 0
dp = [[0 for _ in range(2)] for _ in range(len(prices))]
dp[0][0] = -prices[0] # 第一天就买入股票,花了钱,所以余额为负数
dp[1][0] = 0 # 第一天就不买股票
for i in range(1, len(prices)):
dp[i][0] = max(dp[i-1][0], -prices[i]) # 取最便宜的股票
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i]) # 在不买和买之间权衡
return dp[-1][1] # 最后一个肯定是最大的
def maxProfit1(self, prices: [int]) -> int: # 滚动数组的写法
# 还没有细看
if len(prices) == 1:
return 0
dp = [[0] * 2 for _ in range(2)] # 注意这里只开辟了一个2 * 2大小的二维数组
dp[0][0] = -prices[0]
dp[1][0] = 0
for i in range(1, len(prices)):
dp[i % 2][0] = max(dp[(i-1)%2][0], -prices[i])
dp[i% 2][1] = max(dp[(i-1)%2][1], dp[(i-1)%2][0] + prices[i])
return dp[(len(prices)-1) % 2][1]
def maxProfit2(self, prices: [int]) -> int:
# 看起来是动态规划,其实是贪心的写法,这里dp也不用设置为数组,设置为一个int即可
mi = prices[0]
dp = [0 for _ in range(len(prices))]
dp[0] = 0
for i in range(1, len(prices)):
mi = min(mi, prices[i])
dp[i] = max(dp[i - 1], prices[i] - mi)
return dp[-1]
def maxProfit3(self, prices: [int]) -> int:
# 这里是随想录中的python贪心写法
mi = prices[0]
dp = 0
for i in range(1, len(prices)):
mi = min(mi, prices[i])
dp = max(dp, prices[i] - mi)
return dp
if __name__ == '__main__':
prices = [7,1,5,3,6,4]
prices = [1]
# dp = [[0 for _ in range(2)] for _ in range(len(prices))]
# print(dp)
# prices = [7, 6, 4, 3, 1]
tmp = Solution()
res = tmp.maxProfit2(prices)
print(res)
122.买卖股票的最佳时机II
# 给你一个整数数组prices ,其中prices[i]表示某支股票第i天的价格。
# 在每一天,你可以决定是否购买和 / 或出售股票。你在任何时候最多只能持有一股股票。你也可以先购买,然后在同一天出售。返回你能获得的最大利润 。
#
# 示例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 。总利润为4 。
#
# 示例3:
# 输入:prices = [7, 6, 4, 3, 1]
# 输出:0
# 解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为0 。
class Solution:
def maxProfit(self, prices: [int]) -> int:
if len(prices) == 1:
return 0
dp = [[0 for _ in range(2)] for _ in range(len(prices))]
dp[0][0] = -prices[0]
dp[1][0] = 0
for i in range(1, len(prices)):
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]) #注意这里是和121. 买卖股票的最佳时机唯一不同的地方
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i])
return dp[-1][1] # 最后一个肯定是最大的
# 这个之前用贪心的思路做过,有印象
def maxProfit2(self, prices: [int]) -> int:
res = 0
for i in range(1,len(prices)):
if prices[i] > prices[i-1]:
res += prices[i] - prices[i-1]
return res
if __name__ == '__main__':
price = [7,1,5,3,6,4]
tmp = Solution()
res = tmp.maxProfit(price)
res = tmp.maxProfit2(price)
print(res)