由于DP部分内容太过繁杂,整理一下。这一部分针对一维,主要针对以下选择
- 选择和上一步相同,该步不选择
- 选择当前数,从而再去前面找合适的
# 746. Min Cost Climbing Stairs,每次走一步或者走两步
def minCostClimbingStairs(cost): """ :type cost: List[int] :rtype: int """ n=len(cost) steps=[None]*n# minimum to climb across i if n>0: steps[0]=min(cost[0],0) if n>1: steps[1]=min(cost[0],cost[1]) for i in range(2,n):# 爬过i,意味着从i出发,或者从i-1出发,但选择上上步的值 steps[i]=min(cost[i]+steps[i-1],cost[i-1]+steps[i-2]) print(steps) return steps[-1]
# 198. House Robber, 给定nums,不选择相邻的情况下求最大值
- 要么当前不要,选上一个;要么选当前+上上个的最大值
def rob(nums): """ :type nums: List[int] :rtype: int """ n=len(nums) if n==0: return 0 if n<=2: return max(nums) nums[1]=max(nums[0],nums[1]) for i in range(2,n): nums[i]=max(nums[i-1],nums[i-2]+nums[i]) return nums[-1]
# 213. House Robber II,环形情况,如果最后一个和第一个相邻,那么相当于求两个最大值 range(1,n) & range(n-1)
def rob2(nums): if not nums: return 0 if len(nums) <= 2: return max(nums) def rob_row(nums): res = [0] * len(nums) res[0], res[1] = nums[0], max(nums[0], nums[1]) for i in range(2, len(nums)): res[i] = max(res[i-1], res[i-2] + nums[i]) return res[-1] return max(rob_row(nums[1:]), rob_row(nums[:-1]))
# 740. Delete and Earn, 和上面相似,给定很多数,每选择一个数,要将其相邻的数全删除
- sort them by num and record the frequency
- 如果目前的数与之前不相邻,则相加
- 如果相邻,dp[n] = max(dp[n-1],dp[n-2]+an)
import collections def deleteAndEarn(nums):#不选值相邻的数,每个数带一个频率 """ :type nums: List[int] :rtype: int """ if not nums: return 0 counts = collections.Counter(nums) counts = sorted(counts.items(),key=lambda x:x[0]) cur = [0 for _ in range(len(counts))] cur[0] = counts[0][0]*counts[0][1] if len(counts)>=2: if counts[1][0]!=counts[0][0]+1: cur[1] = cur[0]+counts[1][0]*counts[1][1] else: cur[1] = max(cur[0],counts[1][0]*counts[1][1]) for i in range(2,len(counts)): if counts[i][0]!= counts[i-1][0]+1: cur[i] = cur[i-1]+counts[i][0]*counts[i][1] else: cur[i] = max(cur[i-1],cur[i-2]+counts[i][0]*counts[i][1]) return cur[-1]