DP-LeetCode132. 分割回文串 II

1、题目描述

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。  返回符合要求的最少分割次数

输入: "aab"

输出: 1

解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。

2、代码详解

class Solution(object):
    def minCut(self, s):
        """
        :type s: str
        :rtype: int
        """
        n = len(s)
        INF = float('inf')
        dp = [INF] * (n+1)  # dp[i]为字符串前i个字符s[0...i-1] 最少可以划分成 几个回文串

        if n == 0:
            return 0

        isPalin = self.calcPalin(s)  # 判断回文的二维数组,isPlain[i][j]表示s[i...j]是否是回文串
        print(isPalin)

        dp[0] = 0
        for i in range(n+1):
            for j in range(i):
                if isPalin[j][i-1] == True:  # 表示s[j...i-1]是否是回文串
                    dp[i] = min(dp[i], dp[j]+1)

        return dp[n] - 1  # 返回符合要求的最少分割次数 = 几个回文串 - 1



    # 思想:生成回文串,中心扩展,O(n*n)
    def calcPalin(self, s):
        n = len(s)
        f = [[False]*n for _ in range(n)]

        # 从中心扩展两边
        # odd 奇数,从 中心字符 向两边扩展
        for c in range(n):
            i = j = c
            while i >= 0 and j <= n-1 and s[i] == s[j]:
                f[i][j] = True
                i -= 1
                j += 1
        # even 偶数,从 中心轴线 向两边扩展
        for c in range(n-1):  # 区别
            i = c
            j = c + 1
            while i >= 0 and j <= n-1 and s[i] == s[j]:
                f[i][j] = True
                i -= 1
                j += 1

        return f

s = 'aabbac'
S = Solution()
print(S.minCut(s))  # 返回切割次数,2

dp[i]:表示字符串前i个字符s[0...i-1] 最少可以划分成 几个回文串
isPlain[i][j]:表示s[i...j]是否是回文串

例如,“aabbaac”,切割2次变为[a, abba, c]

isPlain数组为

[True, True, False, False, False, False], 
[False, True, False, False, True, False], 
[False, False, True, True, False, False], 
[False, False, False, True, False, False], 
[False, False, False, False, True, False], 
[False, False, False, False, False, True]

如草稿图

思考:如何打印出切割好的各个回文串?

https://www.jiuzhang.com/problem/palindrome-partitioning-ii/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值