LeetCode 121. 买卖股票的最佳时机
题目链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)
直觉告诉我要贪心算法,章节告诉我得用DP来做,行,都做一下!
贪心:只能买一次,所以我们把最小值记下来,最大值记下来,相减(注意小的其位置要小于大的位置序号)
代码:
#python 贪心策略
class Solution:
def maxProfit(self, prices: List[int]) -> int:
min_price = float('inf') # 初始化最小价格为正无穷大
max_profit = 0 # 初始化最大利润为0
for price in prices:
if price < min_price:
min_price = price # 更新最小价格
elif price - min_price > max_profit:
max_profit = price - min_price # 更新最大利润
return max_profit
DP的话,注意二维DP的列,当为0的时候表示为买了股票的账户最大价值,1表示为没买股票的账户最大价值,详见注释。
代码:
#python #DP做法
class Solution:
def maxProfit(self, prices: List[int]) -> int:
#假设第一天账户余额为0,该题求账户余额最大是多少
n = len(prices) #判断长度
if n == 0 :
return 0
dp = [[0] * 2 for _ in range(n)] #列为0时代表拥有股票当前账户最大价值,为1代表不拥有股票最大的价值
dp[0][0] = - prices[0] #当把第一天的股票买了,当前账户所剩的钱
dp[0][1] = 0 #第一天不操作账户里的钱
for i in range(1, n): #遍历后续情况
dp[i][0] = max(dp[i - 1][0], - prices[i]) #列为0,表示此时拥有股票账户的最大价值,要么就是前一个状态n-1的状态,要么是当前重新在最低点买入该股票
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]) #列为1,表示此时已经卖掉股票账户所拥有的最大价值,要么是和之前卖的钱一样,要么是已经购入股票的余额加上股票卖出的最大价值
return dp[-1][1] #返回最大价值
LeetCode 122. 买卖股票的最佳时机 II
题目链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)
和上一题一样,两种做法都做一下;
贪心:这道题对该只股票可以重复购买,因此我们贪心做法可有如此思路:不断计算当前价格与前一天价格的差值,如果大于0(涨了)就放在股票账户上,小于0(跌了)就不计入了。
代码:
#python #贪心策略
class Solution:
def maxProfit(self, prices: List[int]) -> int:
profit = 0
for i in range(1, len(prices)):
tmp = prices[i] - prices[i - 1]
if tmp > 0: //只要有利润,就加上
profit += tmp
return profit
DP:定义和上一题一样,但是注意一下中间对于每个位置上拥有股票的最大价值,就应该有一个初始状态了,也就是dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])。
代码:
#python #dp做法
class Solution:
def maxProfit(self, prices: List[int]) -> int:
n = len(prices)
if n == 0 :
return 0
dp =[[0] * 2 for _ in range(n)]
dp[0][0] = - prices[0]
dp[0][1] = 0
for i in range(1,n):
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[-1][1]