322. 零钱兑换
题目描述: 322. 零钱兑换.
解法
二维dp,组合问题可以用,求方案数量
class Solution(object):
def coinChange(self, coins, amount):
dp = [[float("inf")] * (amount+1) for _ in range(len(coins)+1)]
dp[0][0] = 0
for i in range(1,len(coins)+1):
for j in range(amount+1):
dp[i][j] = dp[i-1][j]
if j >= coins[i-1]:
dp[i][j] = min(dp[i][j],dp[i][j-coins[i-1]]+1)
return dp[len(coins)][amount] if dp[len(coins)][amount] != float("inf") else -1
注意一定要初始化,并且所有元素最开始应该是一个无穷大的值,因为方案是比小,而不是比大。
滚动dp
class Solution(object):
def coinChange(self, coins, amount):
dp = [float("inf")] * (amount+1)
dp[0] = 0
for i in range(len(coins)):
for j in range(coins[i],amount+1):
dp[j] = min(dp[j],dp[j-coins[i]]+1)
return dp[amount] if dp[amount] != float("inf") else -1
279.完全平方数
题目描述: 279.完全平方数.
解法
滚动dp
class Solution(object):
def numSquares(self, n):
dp = [float("inf")] * (n+1)
dp[0] = 0
for num in range(1,int(n**0.5)+1):
for j in range(num,n+1):
if j >= num*num:
dp[j] = min(dp[j],dp[j-num*num]+1)
return dp[n]
二维dp,组合问题可以用,求方案数量
class Solution(object):
def numSquares(self, n):
nums = [i**2 for i in range(1,int(n ** 0.5)+1)]
dp = [[float("inf")] * (n+1) for _ in range(len(nums)+1)]
dp[0][0] = 0
for i in range(1,len(nums)+1):
for j in range(n+1):
dp[i][j] = dp[i-1][j]
if j >= nums[i-1]:
dp[i][j] = min(dp[i][j],dp[i][j-nums[i-1]]+1)
return dp[len(nums)][n]
139.单词拆分
题目描述: 139.单词拆分.
解法
滚动dp
class Solution(object):
def wordBreak(self, s, wordDict):
dp = [False] * (len(s)+1)
dp[0] = True
for j in range(len(s)+1):
for word in wordDict:
if j>=len(word):
dp[j] = dp[j] or (dp[j-len(word)] and s[j-len(word):j] == word)
return dp[len(s)]
一定要想清楚背包问题是什么,就是用一些内容去填充一个空间,那么这道题就是一个用单词去填充字符串的题目。
此外单词可以重复使用,并且单词是有排列需求的,因此就是完全背包的排列问题,因此先遍历背包,再遍历物品。