力扣题解(统计满足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),则rj=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;

    }
};
相关推荐
依然鸣12 分钟前
PTA团体程序设计天梯赛L2真题讲解L2-005-008
开发语言·数据结构·c++·算法·深度优先·pat考试·图论
imaol140 分钟前
数据结构--树
数据结构
Tongzhi20261 小时前
通芝科技无感考勤一体机:软硬一体,开箱即用
数据结构·数据库·科技·算法·均值算法·数据库开发
linux-hzh3 小时前
百日算法修炼 · Day 09
数据结构·算法·排序算法
淡海水3 小时前
C#与常用数据结构源码剖析-全篇导览
开发语言·数据结构·unity·面试·职场和发展·c#
一米阳光86615 小时前
软考(中级)软件设计师核心笔记(8)数据结构——图
数据结构·笔记·职场发展·软考·软件设计师·中级职称
wabs66617 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
wuyk55518 小时前
2.队列:先进先出的线性数据结构
c语言·数据结构·stm32·单片机
lsylalalala19 小时前
常见的排序算法1
数据结构·算法·排序算法
imaol120 小时前
数据结构---队列
java·数据结构·算法