每日一题|3258. 统计满足 K 约束的子字符串数量 I|滑动窗口

1. 枚举

数据量不大,枚举直接拿下。

class Solution:
    def countKConstraintSubstrings(self, s: str, k: int) -> int:
        res = 0
        for i in range(len(s)):
            count = [0, 0]
            for j in range(i, len(s)):
                count[int(s[j])] += 1
                if count[0] > k and count[1] > k:
                    break
                res += 1
        return res

 2. 滑动窗口

枚举的时间开销是O(n * n),很不美丽,所以需要找到一个不用全部遍历所有子字符串的方法。

如果一个字符串在一个区间内满足该条件,那么其中每一个子串都满足条件。

那么,如何一条不落下计入全部的子字符串呢?

答案是先固定一侧的指针,统计另一侧到这边一共有多少子串。

也就是说,我们对于每一个能够最大限度满足条件的区间求其一端到另一端的全部子串即可。这样一个需要消耗时间的遍历就变成了首尾索引的运算,节省了时间。

那么如何找到然后更新这个“最大长度”区间呢?

一侧动,另一侧不动。滑动窗口。

在出现右侧指针超过界限的时候,移动左侧指针,直到区间重新满足条件。

然后计算右侧指针不动的情况下的子串。

class Solution:
    def countKConstraintSubstrings(self, s: str, k: int) -> int:
        res = 0
        left = 0
        count = [0, 0]
        for i, c in enumerate(s):
            count[int(c) & 1] += 1
            while count[0] > k and count[1] > k:
                count[int(s[left]) & 1] -= 1
                left += 1
            res += i - left + 1
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值