Leetcode 3261. Count Substrings That Satisfy K-Constraint II

  • [Leetcode 3261. Count Substrings That Satisfy K-Constraint II](#Leetcode 3261. Count Substrings That Satisfy K-Constraint II)
    • [1. 解题思路](#1. 解题思路)
    • [2. 代码实现](#2. 代码实现)

1. 解题思路

这一题我们首先可以仿照题目3258的方式通过一个滑动窗口快速得到每一个位置作为起点时其对应的最大K-Constraint的边界。

然后,我们通过如下query函数即可得到任意范围内的substring当中所有的满足K-Constraint的子串个数:

python 复制代码
def query(l, r):
    ans = 0
    for i in range(l, r+1):
        ans += (min(boundaries[i], r+1) - i)
    return ans

return [query(l, r) for l, r in queries]

但是,这个query函数的时间复杂度是 O ( N ) O(N) O(N),叠加上全部的query,整体的算法复杂度就会是 O ( M N ) O(MN) O(MN),时间复杂度过高,无法通过全部的测试样例,因此我们需要对query函数进行一下优化。

显然,如果不考虑这个min函数,那么query函数就可以快速地通过一个累积数组进行实现,只是这个min函数比较麻烦,因此我们对其进行一下拆分,首先找到min函数的这个分界点,然后左侧都满足min(boundaries[i], r+1) = boundaries[i],而右侧都满足min(boundaries[i], r+1) = r+1,此时,我们就可以分成两个部分进行求解:

  • 左侧: s = ∑ i = l k b i − i s = \sum\limits_{i=l}^{k} b_i - i s=i=l∑kbi−i
  • 右侧: s = ∑ i = k + 1 r r + 1 − i s = \sum\limits_{i=k+1}^{r} r+1 - i s=i=k+1∑rr+1−i

前者我们可以通过累积数组来计算,后者我们直接通过等差数列即可求得。

由此,整体的query算法复杂度就降至 O ( 1 ) O(1) O(1)了。

2. 代码实现

给出python代码实现如下:

python 复制代码
class Solution:
    def countKConstraintSubstrings(self, s: str, k: int, queries: List[List[int]]) -> List[int]:
        n = len(s)
        i, j = 0, 0
        cnt = defaultdict(int)
        boundaries = [0 for _ in range(n)]
        while i < n:
            while j < n:
                if cnt["0"] > k and cnt["1"] > k:
                    break
                cnt[s[j]] += 1
                j += 1
            if cnt["0"] > k and cnt["1"] > k:
                boundaries[i] = j-1
            else:
                boundaries[i] = j
            cnt[s[i]] -= 1
            i += 1
            
        cnt = [b-i for i, b in enumerate(boundaries)]
        cs = list(accumulate(cnt, initial=0))
        
        def query(l, r):
            i = max(bisect.bisect_right(boundaries, r), l)
            ans = cs[i] - cs[l] + (r+1) * (r+1-i) - (r+i) * (r+1-i) // 2
            return ans
        
        return [query(l, r) for l, r in queries]

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

相关推荐
Espresso Macchiato11 天前
Leetcode 3748. Count Stable Subarrays
算法·leetcode·职场和发展·leetcode hard·leetcode 3748·leetcode周赛476·区间求和
2401_8414956413 天前
【LeetCode刷题】找到字符串中所有字母异位词
数据结构·python·算法·leetcode·数组·滑动窗口·找到字符串中所有字母异位词
Espresso Macchiato14 天前
Leetcode 3741. Minimum Distance Between Three Equal Elements II
滑动窗口·leetcode medium·leetcode 3741·leetcode周赛475
Espresso Macchiato14 天前
Leetcode 3739. Count Subarrays With Majority Element II
leetcode hard·前序和数组·leetcode双周赛169·leetcode 3739
卷卷的小趴菜学编程1 个月前
Linux系统之----UDP、TCP详解
网络·tcp/ip·udp·滑动窗口·流量控制·拥塞避免·超时重传快重传
苏纪云1 个月前
算法<C++>——双指针 | 滑动窗口
数据结构·c++·算法·双指针·滑动窗口
Tisfy1 个月前
LeetCode 3346.执行操作后元素的最高频率 I:滑动窗口(正好适合本题数据,II再另某他法)
算法·leetcode·题解·滑动窗口·哈希表
Espresso Macchiato1 个月前
Leetcode 3729. Count Distinct Subarrays Divisible by K in Sorted Array
leetcode·leetcode hard·容斥原理·leetcode 3729·leetcode周赛473·前序和数组
Espresso Macchiato1 个月前
Leetcode 3715. Sum of Perfect Square Ancestors
算法·leetcode·职场和发展·leetcode hard·树的遍历·leetcode 3715·leetcode周赛471
Espresso Macchiato1 个月前
Leetcode 3710. Maximum Partition Factor
leetcode·职场和发展·广度优先遍历·二分法·leetcode hard·leetcode 3710·leetcode双周赛167