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。

相关推荐
阿巴~阿巴~3 天前
从滑动窗口到拥塞控制:TCP高效可靠传输的三大支柱
服务器·网络·网络协议·tcp·滑动窗口·流量控制·拥塞控制
CodeAmaz6 天前
常用限流算法详解
滑动窗口·限流算法·令牌桶
Espresso Macchiato10 天前
Leetcode 3791. Number of Balanced Integers in a Range
leetcode hard·leetcode周赛482·leetcode 3791
Espresso Macchiato10 天前
Leetcode 3782. Last Remaining Integer After Alternating Deletion Operations
迭代·leetcode hard·leetcode双周赛172·leetcode 3782
Espresso Macchiato10 天前
Leetcode 3768. Minimum Inversion Count in Subarrays of Fixed Length
滑动窗口·leetcode hard·leetcode双周赛171·leetcode 3768
Espresso Macchiato10 天前
Leetcode 3785. Minimum Swaps to Avoid Forbidden Values
leetcode hard·leetcode周赛481·leetcode 3785
weixin_4617694010 天前
3. 无重复字符的最长子串
c++·算法·滑动窗口·最长字串
Espresso Macchiato10 天前
Leetcode 3786. Total Sum of Interaction Cost in Tree Groups
leetcode hard·leetcode 3786·leetcode周赛481
nju_spy11 天前
12月力扣每日一题(划分dp + 单调栈 + 堆 + 会议安排)
算法·leetcode·二分查找·动态规划·滑动窗口·单调栈·最大堆
2401_8414956413 天前
【LeetCode刷题】爬楼梯
数据结构·python·算法·leetcode·动态规划·滑动窗口·斐波那契数列