力扣热题100学习day09——动态规划

322.零钱兑换

(一)我的思想:

(1)明确 dp 数组的含义,dp[n] 表示装满容量 n 所需要的最少零钱数

(2)确定递归公式 dp [j] = min( dp [ j - coins [ i ] ], dp [ j ] )

(3)初始化 dp 数组,dp [0] = 0,其余 dp [j] 初始值都是一个最大数(在这里我取amount+1为最大值,因为题目中要求amount最大值为10000),这样进行 min 操作时才不会被覆盖更小的值

(4)确定遍历顺序,先遍历背包再遍历物品求排列数,先遍历物品再遍历背包求组合数

代码实现如下:

class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        dp = []
        dp.append(0)
        for i in range(1,amount+1):
            dp.append(float('inf'))
        if amount==0:
            return 0
        for coin in coins:
            for j in range(coin,amount+1):
                dp[j] = min(dp[j-coin]+1,dp[j])
        if dp[amount]==float('inf'):
            return -1
        return dp[amount]

139.单词拆分

(一)我的思想:按照想当然的思路,不断查找字典中是否存在构成字符串 s 的部分,有的话则缩短原来的字符串 s ,最后通过判断字符串是否被缩短为空来判断字符串 s 是否能由字典中元素构成,乍一看好像挺合理,但实际运行时漏洞百出,比如例子字符串 s =cars,字典元素car,ca,rs,按照我的思路第一轮循环缩短字符后肯定无法正确判断了,输出false,但理论上应该由后面ca和rs拼出cars。

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        for word in wordDict:
            if word in s:
                print(word,s)
                s = s.replace(word,"")
                self.wordBreak(s,wordDict)
        if s=="":
            return True
        return False

(二)网上思路:很多题目都可以用装背包思想来理解,比如这道题,可以理解为能否用字典中的元素装满一个容量为字符串 s 的背包,但是定义 dp 数组时是使用字符串长度 i 作为下标,下标永远是一个 int 类型的,而如果我想用一个字符串类型作下标,是正常思路,但代码怎么知道怎么查分出你想的字符串呢,还是要一个字符一个字符的添加,看添加进的一串字符是否出现在字典里。

代码实现如下:

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        dp = []
        for i in range(len(s)+1):
            dp.append(False)
        dp[0] = True
        
        for i in range(1, len(s)+1):
            for j in range(0, i):
                if s[j:i] in wordDict and dp[j]:
                    dp[i] = True
        return dp[len(s)]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值