LeetCode 132 Palindrome Partitioning ||

LeetCode 132 Palindrome Partitioning ||

分析

这是一道动态规划题,基本上需要考虑一个字符串的子字符串的题目,都能往动归上考虑(子问题)。
举例子:
现在假设我们有一个字符串

# 长度为8
abcdaaaa
# 它有如下几种分法
abcd aaaa
   j    i
abcda aaa
    j   i
abcdaa aa
     j  i
abcdaaa a
      j i
abcdaaaa 
# 最后一行,j i 重合了

我们把它看作左半部分和右半部分,现在,问题的答案就变成了把左半部分分解所需的步数再加1
用**f[i]**表示把长度为i的字符串分解所需的最小步数

if s[i, j+1]是一个回文子串:
	f[i] = min(f[i], f[j]+1)

现在问题就变成了如何判断一个子串是不是回文的???
在python里,这个有小技巧的

s[i:j+1] == s[i:j+1][::-1]

不过这种小技巧会复制子串。
此处写一个动归算法来判断子串是否回文

# left, right
# c[l][r]表示,l,r这个区间里的子串是否回文
c[l][r] = s[l] == s[r] and l+1 > r-1 or c[l+1][r-1]
# c[l+1][r-1]就是已经解决的子问题

Code

class Solution:
    def minCut(self, s: str) -> int:
        n = len(s)
        c = [[False] * n for _ in range(n)]
        
        # 为了判断回文子串
        for i in range(1, n+1):
            for j in range(n+1-i):
                l, r = j, j+i-1
                tag = l+1 > r-1 or c[l+1][r-1]
                c[l][r] = s[l] == s[r] and tag
                
        f = [2**31] * (n+1)
        f[0] = 0  # 保证从f[0]转移
        for i in range(1, n+1):
            for j in range(1, i+1):
                if c[j-1][i-1]:
                    f[i] = min(f[i], f[j-1]+1)
                    
        # print(c)
                    
        return f[n]-1 
        # 减一是因为,我这里定义最少能分割成多少个子串
        # 答案是要求出剪几刀

欢迎一起来参与leetcode刷题项目

刷题的GitHub: github链接.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值