Leetcode 3003. Maximize the Number of Partitions After Operations

这篇文章介绍了如何解决LeetCode10038题,通过动态规划策略最大化分割后partition的数量。作者分享了解题思路,指出考虑字符出现次数和变换次数对分割数的影响,给出了Python代码实现,以及代码的时间和空间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 解题思路

这一题我看实际比赛当中只有72个人做出来,把我吓得够呛,还以为会很难,不过实际做了之后发现其实挺简单的,不知道啥情况……

思路上来说,这道题还是动态规划的思路,要考虑能够分割的partition的最大数目,我们只需要考察每一位上的字符是否需要发生变化以及变化前后分割数目的变化即可。

显然,如果一个字符在当前的partition当中没有出现过,那么这个字符显然不需要进行变化,因为不会因此而产生额外的收益。

而如果该字符在当前partition当中已经出现过,但是变化的次数已经过了,那么我们同样不需要进行考虑,只能顺序进行partition的切分看看能分割成多少个partition。

而如果该字符在当前partition当中已经出现过,且变换的机会还没使用,我们就要遍历一下将其变换成所有当前partition当中还未出现过的字符以及保留变换机会不在此进行变换的情况下能够获得的partition的最大值返回即可。

而关于当前partition当中已出现过哪些字符,我们可以用一个int值来记录一下各个字符是否已经有出现过。

此时,总的时间复杂度就是 O ( 26 × 2 × N ) O(26 \times 2 \times N) O(26×2×N)

2. 代码实现

给出python代码实现如下:

class Solution:
    def maxPartitionsAfterOperations(self, s: str, k: int) -> int:
        if len(set(s)) < k or k == 26:
            return 1
        
        n = len(s)
        
        @lru_cache(None)
        def dp(idx, change, status):
            if idx >= n:
                return 0 if status == 0 else 1
            loc = ord(s[idx]) - ord('a')
            if status & (1<<loc) == 0:
                if Counter(bin(status))["1"] == k:
                    return 1 + dp(idx, change, 0)
                else:
                    return dp(idx+1, change, status | (1<<loc))
            else:
                ans = dp(idx+1, change, status)
                if change > 0:
                    if Counter(bin(status))["1"] == k:
                        for i in range(26):
                            if status & (1 << i) == 0:
                                ans = max(ans, 1 + dp(idx+1, change-1, 1 << i))
                    else:
                        for i in range(26):
                            if status & (1 << i) == 0:
                                ans = max(ans, dp(idx+1, change-1, status | (1 << i)))
                return ans
            
        return dp(0, 1, 0)

提交代码评测得到:耗时719ms,占用内存119.8MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值