leetcode 664. 奇怪的打印机

leetcode 664. 奇怪的打印机

动态规划!!

dp[i][j]是字符串区间[i,j]中需要的最少的打印次数。

  • 首先初始化 dp[i][j]为很大的值。
  • 打印一个字符串需要 1 次,即为 dp[i][i] = 1
  • 当字符串长度大于等于 2 时,判断两端字符是否相等?即为s[i] == s[j] ?
    1. 如果 s[i] == s[j] 那么 dp[i][j] = dp[i][j-1]
    2. 如果 s[i] != s[j] 那么就需要遍历一下,在[i,j-1]中找一个分割点 k,找到能够使得两边之和最小的分割点。即为dp[i][j] = min(dp[i][k] + dp[k+1][j])

找到转移方程了,接下来就是如何遍历的问题,自底向上 ,就是从矩阵的右下角遍历到右上角。找好边界就可以顺利 AC!

class Solution:
    def strangePrinter(self, s: str) -> int:
        n = len(s)
        dp = [[2**20]*n for i in range(n)]
        for i in range(n):
            dp[i][i] = 1
        for i in range(n,-1,-1):
            for j in range(i+1,n):
                if s[i] == s[j]:
                    dp[i][j] = dp[i][j-1]
                else:
                    for k in range(i,j):
                        dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j])
        return dp[0][n-1]
复杂度分析

时间复杂度: O ( n 2 ) O(n^2) O(n2) ,其中 n 是字符串的长度。
空间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n 是字符串的长度。我们需要保存所有 n 2 n^2 n2 个状态

遇到的问题
  1. 题目读完了没有反应过来可以使用动态规划
  2. 动态规划的遍历顺序
  3. range的使用。range()语法:

range(start,end,step=1),setp默认为1

  • 正序遍历:
    range(10):默认step=1,start=0,生成可迭代对象,包含[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    range(1,10):指定start=1,end=10,默认step=1,生成可迭代对象,包含[1, 2, 3, 4, 5, 6, 7, 8, 9]
    range(1,10,2):指定start=1,end=10,step=2,生成可迭代对象,包含[1, 3, 5, 7, 9]
  • 逆序遍历:
    range(9,-1,-1):step=-1,start=9,生成可迭代对象,包含[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

你可能感兴趣的:(leetcode刷题,python)