2020-2-25 刷题总结

2020-02-25  本文已影响0人  madao756

0X00 leetcode 做了 4 道

0X01 每道题的小小记录

今天主要做了「划分型动态规划」两道,一道「博弈型动态规划」一道 比较简单的动态规划

279. Perfect Squares

像这种划分数字的,划分字符串的,可以考虑「划分型动态规划」

class Solution:
    def numSquares(self, n: int) -> int:
        # 划分形动态规划
        # f(x) = min[f(x - 1 * 1), f(x - 2 * 2), ..., f(x- j * j)] + 1

        record = [0] * (n+1)

        for x in range(1, n+1):
            t = float("inf")
            j = 1
            while j*j <= x:
                if t > record[x - j*j]:
                    t = record[x - j*j]
                j += 1

            record[x] = t + 1 

        return record[x]

132. Palindrome Partitioning II

class Solution:
    def minCut(self, s: str) -> int:
        # 用动态规划做
        # 最后状态
        # 长度为 n 的字符串,所用的最少回文 f(n) = 
        # 其中 j 是 n-j~n 是回文的字符 min(f(n-1), min(n-j), ...) + 1
        
        if s == "": return 0
        m, n  = len(s), len(s)
        self.isPalin = [[False for _ in range(m)] for _ in range(n)]
        self.findAll(s)
        record = [0] * (m+1)

        for x in range(1, m+1):
            record[x] = float("inf")
            for j in range(x):
                if self.isPalin[j][x-1]:
                    record[x] = min(record[x], record[j] + 1)
        
        return record[-1] - 1

    def findAll(self, s):
        m = len(s)
        # odd 
        for c in range(m):
            i = j = c
            while i > -1 and j < m and s[i] == s[j]:
                self.isPalin[i][j] = True
                i -= 1
                j += 1
        
        # even
        for c in range(m-1):
            i = c
            j = c + 1
            while i > -1 and j < m and s[i] == s[j]:
                self.isPalin[i][j] = True
                i -= 1
                j += 1

这里积累一个找所有回文的模板:

def findAll(self, s):
        m = len(s)
        # odd 
        for c in range(m):
            i = j = c
            while i > -1 and j < m and s[i] == s[j]:
                self.isPalin[i][j] = True
                i -= 1
                j += 1
        
        # even
        for c in range(m-1):
            i = c
            j = c + 1
            while i > -1 and j < m and s[i] == s[j]:
                self.isPalin[i][j] = True
                i -= 1
                j += 1

292. Nim Game

博弈型动态规划,关键在于:找到让对手必败的状态.而且思考的方式不是最后一步,而是第一步

但是用过动态规划做超时了...

class Solution:
    def canWinNim(self, n: int) -> bool:
        # 动态规划去做这个题目
        # 初始状态 1, 2, 3 都是 True
        # 接下来的状态看能不能转换到必败的状态
        # 如果不能,那么自己必败
        
        if n<= 3: return True
        a = b = c = True
        for i in range(4, n+1):
            t = False if a and b and c else True
            a, b, c = b, c, t

        return c

因为有一个数学规律,所以写成:

class Solution:
    def canWinNim(self, n: int) -> bool:
        return n % 4 != 0

322. Coin Change

一道比较简单的动态规划

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        if len(coins) == 0: return -1

        record = [0] * (amount+1)

        def helper(idx):
            if idx == 0: return 0
            if idx < 0: return float("inf")
            return record[idx]

        for i in range(1, amount+1):
            record[i] = min([helper(i - v) for v in coins]) + 1
        
        return -1 if record[amount] == float("inf") else record[amount]
上一篇 下一篇

猜你喜欢

热点阅读