文章目录
17.打家劫舍
198.打家劫舍
dp[i]表示第i家能获得的最高金额
dp[i] = max(dp[i-1], dp[i-2]+nums[i])
dp[0] = nums[0], dp[1] = max(nums[0], nums[1])
class Solution:
def rob(self, nums: List[int]) -> int:
if len(nums) == 0: # 如果没有房屋,返回0
return 0
if len(nums) == 1: # 如果只有一个房屋,返回其金额
return nums[0]
dp = [0]*len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i in range(2,len(nums)):
dp[i] = max(dp[i-1], dp[i-2]+nums[i])
return dp[-1]
18.打家劫舍II
213.打家劫舍II
围成环,即不带第一个和不带最后一个两种情况的最大值
class Solution:
def dprob(self, nums: List[int]) -> int:
if len(nums)==0: return 0
if len(nums)==1: return nums[0]
dp = [0]*len(nums)
dp[0] = nums[0]
dp[1] = max(nums[0],nums[1])
for i in range(2,len(nums)):
dp[i] = max(dp[i-1],dp[i-2]+nums[i])
return dp[-1]
def rob(self, nums: List[int]) -> int:
if len(nums)==0: return 0
if len(nums)==1: return nums[0]
r0 = self.dprob(nums[:-1])
r1 = self.dprob(nums[1:])
return max(r0,r1)
19.打家劫舍 III
337.打家劫舍 III
后序遍历,每个节点分为偷与不偷
不偷:max(左不偷,左偷)+(右不偷,右偷)
偷:左不偷+右不偷+自身值
class Solution:
def traversal(self, root: TreeNode) -> int:
if not root: return (0,0)
left = self.traversal(root.left)
right = self.traversal(root.right)
return (max(left)+max(right),left[0]+right[0]+root.val)
def rob(self, root: Optional[TreeNode]) -> int:
return max(self.traversal(root))
20.买卖股票的最佳时机
121. 买卖股票的最佳时机
dp[i][0]持有,dp[i][1]不持有
dp[i][0]=max(之前持有,买了)=max(dp[i-1][0],-price[i])
dp[i][1]=max(之前不持有,卖了)=max(dp[i-1][1],dp[i-1][0]+price[i])
dp[0][0]=-price[0],dp[0][1]=0
class Solution:
def maxProfit(self, prices: List[int]) -> int:
dp = [[0]*2 for _ in range(len(prices))]
dp[0][0] = -prices[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]
21.买卖股票的最佳时机II
122.买卖股票的最佳时机II
与20的区别:dp[i][0]=max(之前持有,买了)=max(dp[i-1][0],dp[i-1][1]-price[i])
class Solution:
def maxProfit(self, prices: List[int]) -> int:
dp = [[0]*2 for _ in range(len(prices))]
dp[0][0] = -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[-1][1]
22.买卖股票的最佳时机III
123.买卖股票的最佳时机III
dp[i]的定义:
dp[i][0]不操作;dp[i][1]第一次持有;dp[i][2]第一次不持有;dp[i][3]第二次持有;dp[i][4]第二次不持有
递推公式:
dp[i][0] = dp[i-1][0]
dp[i][1] = max(之前第一次持有dp[i-1][1],第一次买入dp[i-1][0]-prices[i])
dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i])
dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i])
dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i])
初始化:
dp[0][0]=0
dp[0][1]=-prices[0]
dp[0][2]=0
dp[0][3]=-prices[0]
dp[0][4]=0
class Solution:
def maxProfit(self, prices: List[int]) -> int:
dp = [[0]*5 for _ in range(len(prices))]
dp[0][0]=0
dp[0][1]=-prices[0]
dp[0][2]=0
dp[0][3]=-prices[0]
dp[0][4]=0
for i in range(1,len(prices)):
dp[i][0] = dp[i-1][0]
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i])
dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i])
dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i])
dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i])
return dp[-1][4]
22.买卖股票的最佳时机IV
188.买卖股票的最佳时机IV
最多k次,即把21中的2换成对应的k
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
dp = [[0]*(2*k+1) for _ in range(len(prices))]
dp[0][0]=0
for i in range(1,k+1):
dp[0][2*i-1] = -prices[0]
dp[0][2*i] = 0
for i in range(1,len(prices)):
dp[i][0] = dp[i-1][0]
for j in range(1,k+1):
dp[i][2*j-1] = max(dp[i-1][2*j-1],dp[i-1][2*j-2]-prices[i])
dp[i][2*j] = max(dp[i-1][2*j],dp[i-1][2*j-1]+prices[i])
return dp[-1][-1]
23.最佳买卖股票时机含冷冻期
309.最佳买卖股票时机含冷冻期
dp[i][0]持有,之前就持有、冷冻期第二天买入、不持有期买入;
dp[i][1]卖出当天,持有期卖了;
dp[i][2]冷冻期,卖出第二天;
dp[i][3]不持有,冷冻期第二天、之前就不持有
class Solution:
def maxProfit(self, prices: List[int]) -> int:
dp = [[0]*4 for _ in range(len(prices))]
dp[0][0] = -prices[0]
for i in range(1,len(prices)):
dp[i][0] = max(dp[i-1][0],dp[i-1][2]-prices[i],dp[i-1][3]-prices[i])
dp[i][1] = dp[i-1][0]+prices[i]
dp[i][2] = dp[i-1][1]
dp[i][3] = max(dp[i-1][3],dp[i-1][2])
return max(dp[-1])
24.买卖股票的最佳时机含手续费
714.买卖股票的最佳时机含手续费
和21相比,卖出的时候多花手续费
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
dp = [[0]*2 for _ in range(len(prices))]
dp[0][0] = -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]-fee)
return dp[-1][1]