力扣题解(统计满足k约束的子字符串数目)

3261. 统计满足 K 约束的子字符串数量 II

已解答

困难

相关标签

相关企业

提示

给你一个 二进制 字符串 s 和一个整数 k

另给你一个二维整数数组 queries ,其中 queries[i] = [li, ri]

如果一个 二进制字符串 满足以下任一条件,则认为该字符串满足 k 约束

  • 字符串中 0 的数量最多为 k
  • 字符串中 1 的数量最多为 k

返回一个整数数组 answer ,其中 answer[i] 表示 s[li..ri] 中满足 k 约束 的 子字符串 的数量。

思路:

首先,对于一个给定的l到r区间,可以分成两部分,即l到k和k到r,分界处使得l到k中任意子串都满足k约束,k到r可能满足可能不满足k约束,这样,l到k这一段区间的子字符串的个数就是k-l+1,k-l,k-l-1.......1,总共(k-l+1)*(k-1+2)/2;就是单纯等差数列求和。对于k到r这个区间,则可以考虑用前缀和数组来求解,规定前缀和数组是从0到当前位置的所有子字符串的数目,这样两端点相减就是k到r这一块的子字符串的个数。那么,根据分析,需要求的就是每一个端点的前缀和数组和每个点满足右侧某段点rr到当前点的区间内的所有点都符合子字符串的最大rr。

对于求解右端点,可以利用双指针的算法,思路是找每个右端点是哪个左端点的的符合条件的右端点,这样,对于一个右端点更大的位置,其对应的左端点一定是更大的,两指针都是只能向右侧移动,具体求解办法就是遍历字符串,对于下标i,如果当前j下标到i下标符合k约束(代码中是找到最右侧不符合的那个那个i),则r[j]=i,否则j++一直到符合k约束。对于求的前缀和,则可以利用j++直到符合k约束这一步,因为此时的j就是对于i这个位置,以i为右端点的最长符合k约束的子字符串,因此对于以i为右端点,长度在j到i之间的子串,一定都符合k约束,因此i这个点作为右端点所能提供的子字符串的个数就是i-j+1,这样就可以更新前缀和了。

对于每个查找区间l到r,首先找到l的右端点,然后和r比较,如果右端点小于r,则分成两个部分l到右端点和右端点到r分别求子字符串的个数,否则则只需要求l到r的子字符串的个数(此时表示l到r内任意长度子字符串都符合k约束)。

本题存在很多边界情况,且数组表示的意义很多是不符合条件的第一个边界,因此某些地方求长度实际上是需要主要要减小的。另外,还需要注意前缀和的下标。

复制代码
class Solution {
public:
   typedef long long LL;
    vector<long long> countKConstraintSubstrings(string s, int k, vector<vector<int>>& queries) {
        int n=s.size();
        vector<LL>sum(n+1,0);
        vector<int>count(2,0);
        vector<int>right(n,n);
        for(int i=0,j=0;i<n;i++)
        {   
            count[s[i]-'0']++;
            while(count[0]>k&&count[1]>k)
            {
               count[s[j]-'0']--;
               right[j]=i;
               j++;
            }
            sum[i+1]=(LL)sum[i]+i-j+1;
        }
        vector<LL>res;
        for(int i=0;i<queries.size();i++)
        {
             int l=queries[i][0],r=queries[i][1];
             int j=min(right[l],r+1);
             LL t1=(LL)(j-l)*(j-l+1)/2;
             LL t2=sum[r+1]-sum[j];
             res.push_back(t1+t2);
        }
        return res;

    }
};
相关推荐
ysa0510301 小时前
虚拟位置映射(标签鸽
数据结构·c++·笔记·算法
Yue丶越1 小时前
【C语言】深入理解指针(二)
c语言·开发语言·数据结构·算法·排序算法
程序员东岸2 小时前
数据结构杂谈:双向链表避坑指南
数据结构·链表
Shinom1ya_2 小时前
算法 day 46
数据结构·算法
952362 小时前
数据结构-链表
java·数据结构·学习
小龙报3 小时前
算法通关指南:数据结构和算法篇 --- 队列相关算法题》--- 1. 【模板】队列,2. 机器翻译
c语言·开发语言·数据结构·c++·算法·学习方法·visual studio
晨非辰4 小时前
【数据结构初阶】--从排序算法原理分析到代码实现操作,参透插入排序的奥秘!
c语言·开发语言·数据结构·c++·算法·面试·排序算法
三川6985 小时前
排序算法介绍
数据结构·算法·排序算法
学编程就要猛14 小时前
数据结构初阶:Java中的Stack和Queue
数据结构
是苏浙14 小时前
零基础入门C语言之C语言实现数据结构之顺序表
c语言·开发语言·数据结构