LeetCode132-分割回文串II

前天晚上做了一个梦

具体内容就不细说了

但这个情景经常是出现在我的梦境里

让我不得不好好正视它

于是昨天一天都是恍恍惚惚的

不知道怎么说

希望时间能够冲淡吧


132-分割回文串II

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

返回符合要求的最少分割次数。

示例:

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

思路:

这题是第131题-分割回文串的进阶版,在第131题中我是用到了回溯法,对第131题不熟悉的朋友可以先看看我写的这篇文章。

https://blog.csdn.net/weixin_36431280/article/details/92383075

本来想这题也生搬硬套回溯法,结果是超出时间限制了,最后没办法用了动态规划法来解决。我突然是发现了一条规律:执行效率:动态规划法 > 回溯法。下面我将分别贴出这两种算法的代码。

回溯法

当时因为是第131题用到了该方法,很快解决了问题,所以这题我是毫不犹豫就用该方法,只是做了一些改进,没想到超出时间限制了,这确实是有点超乎我意料了。不过想想也确实,这题号称也是困难级题目了,如果就这么easy解出来了,那有点掉面子了。

本题与第131题最大的不同就是:第131题中是使用了split_result列表来收集最终的分割结果,而此题是用min_split 来专门记录分割的最少次数,参数不一样,所以代码会有些不同。

代码如下:

class Solution(object):
    # 本题采用回溯法,其实和第131题特别类似
    def minCut(self, s):
        """
        :type s: str
        :rtype: int
        """   
        if len(s) <= 1:
            return 0

        def back(start=0, min_split = len(s), res=[]):
            if start >= len(s):
                min_split = min(min_split, len(res)-1)
                return min_split
            for end in range(start+1, len(s)+1):
                split_s = s[start:end]
                if split_s == s[start:end][::-1]:
                    min_split = back(end, min_split, res+[split_s])
            return min_split
        return back()


if __name__ == "__main__":
    s = "aab"
    min_split = Solution().minCut(s)
    print(min_split)

动态回归法:

在介绍该算法之前,大家可以先看看我之前专门介绍动态回归法的一篇文章,相信会对你有所帮助:

https://blog.csdn.net/weixin_36431280/article/details/86616672

对于此题呢,首先有如下操作:

此处有一条规律非常重要:

对于起点下标值为start,终点下标值为end的字串s[start:end]来说:
          如果存在:s[start:end] == s[start:end][::-1]
          那么就有record[end] = record[start]+1

因为本题求得是最少分割次数,我们只需要遍历(0,end)之间的字串,求其最小值即可得出答案。

代码如下:

class Solution(object):
    # 本题采用动态规划方法,回溯法超出时间限制了
    def minCut(self, s):
        """
        :type s: str
        :rtype: int
        """   
        if len(s) <= 1:
            return 0
        # 定义标记列表
        record = [index for index in range(-1, len(s))]
        for end in range(1, len(s)+1):
            for start in range(end):
                if s[start:end] == s[start:end][::-1]:
                    record[end] = min(record[end], record[start]+1)
        return record[-1]


if __name__ == "__main__":
    s = "aba"
    min_split = Solution().minCut(s)
    print(min_split)

不过执行效率也是很一般,在30%左右。

如果大家有更好的方法,也希望积极留言啊!!! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习的学习者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值