对于零钱兑换这种由一个数组凑一个数的问题的小总结

LeetCode 322. 零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

输入: coins = [1, 2, 5], amount = 11
输出: 3 
解释: 11 = 5 + 5 + 1
示例 2:

输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。

class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        if amount==0: return 0
        coins.sort()
        if amount < coins[0]: return -1
        dp=[float('inf')]*(amount+1)  #对于不同金额,需要的最少硬币数
        dp[0] = 0
        for coin in coins:
            for i in range(coin, amount+1):
                dp[i] = min(dp[i], dp[i-coin]+1)  
                
        if dp[amount]== float('inf'): return -1
        else: return dp[amount]   

LeetCode 416. 分割等和子集

给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

注意:

每个数组中的元素不会超过 100
数组的大小不会超过 200
示例 1:

输入: [1, 5, 11, 5]

输出: true

解释: 数组可以分割成 [1, 5, 5] 和 [11].
 

示例 2:

输入: [1, 2, 3, 5]

输出: false

解释: 数组不能分割成两个元素和相等的子集.

class Solution(object):
    def canPartition(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        #这道题感觉更绕了一些弯,我也是看了评论懂的。。那就是其实它也是在数组里找数去凑
        #sum(nums)//2这样一个数;和硬币那道题很像,但要注意的问题是,不能重复使用同一个数。

        nums_sum = sum(nums)
        if nums_sum % 2 == 1: return False
        dp = [0] * (nums_sum//2+1)  # 0表示不能计算得到这个数,1表示可以。
        dp[0] = 1
        nums.sort()                 #这个就无所谓了,加不加都行
        for num in nums:
            dp2 = dp[:]             #用另一个列表来进行累加数更新,原因是数不能重复使用;注意不能写成dp2 = dp
            for i in range(num, nums_sum//2+1):
                if dp[i-num]==1: dp2[i]=1
            dp = dp2[:]

        if dp[nums_sum//2]==1: return True
        else: return False

 

你可能感兴趣的:(捣鼓)