代码随想录算法训练营第四十五天| LeetCode322. 零钱兑换、LeetCode279.完全平方数、LeetCode139.单词拆分

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)]

一定要想清楚背包问题是什么,就是用一些内容去填充一个空间,那么这道题就是一个用单词去填充字符串的题目。
此外单词可以重复使用,并且单词是有排列需求的,因此就是完全背包的排列问题,因此先遍历背包,再遍历物品。

你可能感兴趣的:(算法)