边工作边刷题:70天一遍leetcode: day 52-1

Coin Change

要点:一开始用了按amount循环的dp方法,结果对于大数,比如9936就TLE了。dp实际就是一种bottom up的方法(而recursion是top-down)。所以另一种dp方法就是把已经cover的值放到集合中,下一步从集合中取出每一个值更新后再加入集合。可以看出这是BFS。这样循环的次数只有达到目标需要的步数。

  • 本质上说,dp vs. recursion和bfs vs. dfs是orthogonal的:前者是纵向的方向,后者是横向的方向。
  • 最佳解法是从两边同时搜索,当然中间相遇处要用intersection

错误点

  • bfs不能只将队头元素取出就进入下一循环(or 下一步)。而是要同时把本层元素全部遍历
  • python的set初始化要用list作为输入,而不是一个元素
class Solution(object):
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        sums = collections.deque([0])
        visited = set()
        step = 0
        while amount not in sums and min(sums)<amount:
            n = len(sums)
            for i in xrange(n):
                cur = sums.popleft()
                for c in coins:
                    if cur+c not in visited:
                        visited.add(cur+c)
                        sums.append(cur+c)
            step+=1
            # print sums, visited, step
        
        return step if amount in sums else -1