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。

相关推荐
GEEK零零七7 天前
Leetcode 159. 至多包含两个不同字符的最长子串
算法·leetcode·滑动窗口
Espresso Macchiato12 天前
Leetcode 3563. Lexicographically Smallest String After Adjacent Removals
动态规划·leetcode hard·leetcode周赛451·leetcode 3563
Espresso Macchiato12 天前
Leetcode 3562. Maximum Profit from Trading Stocks with Discounts
动态规划·背包问题·leetcode hard·leetcode 3562·leetcode周赛451
卷卷的小趴菜学编程1 个月前
算法篇-----滑动窗口
数据结构·算法·双指针·滑动窗口·哈希表·数组相关
Espresso Macchiato1 个月前
Leetcode 3530. Maximum Profit from Valid Topological Order in DAG
动态规划·leetcode hard·拓扑序列·leetcode 3530·leetcode双周赛155
满怀10151 个月前
【数据通信完全指南】从物理层到协议栈的深度解析
5g·滑动窗口·数据封装·crc校验·qam调制
阳洞洞1 个月前
滑动窗口leetcode 209和76
算法·leetcode·双指针·滑动窗口
2401_858286111 个月前
CC52.【C++ Cont】滑动窗口
开发语言·数据结构·c++·算法·leetcode·滑动窗口
阳洞洞1 个月前
leetcode 2516. 每种字符至少取 K 个
算法·leetcode·滑动窗口
Y1nhl2 个月前
基础算法:滑动窗口_python版本
开发语言·python·算法·力扣·滑动窗口