LeetCode 1525. Number of Good Ways to Split a String(字符串的好分割数目)

问题描述

LeetCode 1525 I
LeetCode 1525 I

解决思路与代码实现


这道题初看起来,暴力求解的规模似乎也不是很大,只需要从头至尾对字符串做一次遍历即可,于是笔者很自然地尝试了一下暴力求解:

class Solution(object):
    def numSplits(self, s):
        """
        :type s: str
        :rtype: int
        """

        num_good = 0
        for i in range(1, len(s)):
            if len(set(s[: i])) == len(set(s[i:])):
                num_good += 1

        return num_good

然而,提交后运行超时,超时的算例是一个长度为 24485 的超长字符串(由于字符串过长,此处暂不列出)。
反思前面暴力求解的代码,可以看出,每次循环的 set 函数,会消耗很多时间,而在对字符串从左向右的遍历过程中,左右两侧子串的 set 的值一定程度是可以复用的。
因此,可以参考动态规划的思想,定义一个集合用来记录左侧子串出现过的字符,定义一个字典以记录右侧子串剩余的字符及出现次数,从左向右遍历,每次循环对集合和字典的内容进行微调即可。
修改后的代码如下:

class Solution(object):
    def numSplits(self, s):
        """
        :type s: str
        :rtype: int
        """

        # 左侧子串的字符集合;右侧子串的字符字典
        set_left, dict_right = set(), {}
        for c in s:
            if c in dict_right.keys():
                dict_right[c] += 1
            else:
                dict_right[c] = 1

        num_good = 0
        for c in s:
            if c not in set_left:  # 若当前字符不在左侧子串的字符集合中,则向集合中加入该字符
                set_left.add(c)

            dict_right[c] -= 1  # 在右侧子串的字符字典中,将该字符的出现次数减 1
            if not dict_right[c]:  # 若更新后的出现次数为 0,则在字典的 key 中删除该字符
                dict_right.pop(c)

            if len(set_left) == len(dict_right):
                num_good += 1

        return num_good

运行效果

运行效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值