当前位置: 首页 > news >正文

DeepSeek LeetCode 3261. 统计满足 K 约束的子字符串数量 II Java实现

这道题是 LeetCode 3261. 统计满足 K 约束的子字符串数量 II,要求高效处理多个查询,统计每个查询区间内满足 K 约束的子串数量。

题目回顾

K 约束定义:字符串中 '0' 或 '1' 的个数 不超过 K。

关键难点:需要 O(1) 或 O(log n) 处理每个查询,不能暴力枚举。

解题思路

1. 找到每个位置 i 作为左端点时,最远可以到达的右端点
对于每个左端点 left,找到最大的 right 使得 [left, right] 满足 K 约束。
利用滑动窗口(双指针)在 O(n) 内完成。
2. 构建前缀和数组
设 maxRight[i] = 以 i 为左端点的最大可行右端点(包含)。
对于查询 [l, r],对于左端点 i 在 [l, r] 范围内:
· 如果 maxRight[i] >= r,说明以 i 开头的子串从 i 到 r 都满足,贡献 (r - i + 1) 个。
· 如果 maxRight[i] < r,贡献 (maxRight[i] - i + 1) 个。
但直接遍历会超时,需要优化。
3. 前缀和 + 二分查找优化
由于 maxRight 数组单调不减(可以用滑动窗口证明),我们可以:
· 预处理 prefixSum[i] 表示以 0..i 为左端点的累计子串数。
· 对于查询 [l, r],二分找到最后一个位置 p 使得 maxRight[p] < r。
· 那么:
· 对于左端点 i ∈ [l, p],每个贡献 (maxRight[i] - i + 1)
· 对于左端点 i ∈ [p+1, r],每个贡献 (r - i + 1)
两部分都能用前缀和快速计算。

Java 实现

```java
class Solution {
public long[] countKConstraintSubstrings(String s, int k, int[][] queries) {
int n = s.length();
char[] arr = s.toCharArray();

// 1. 滑动窗口计算 maxRight[i]
int[] maxRight = new int[n];
int[] cnt = new int[2]; // cnt[0] 数0的个数,cnt[1] 数1的个数
int right = 0;
for (int left = 0; left < n; left++) {
while (right < n && (cnt[0] + (arr[right] == '0' ? 1 : 0) <= k ||
cnt[1] + (arr[right] == '1' ? 1 : 0) <= k)) {
cnt[arr[right] - '0']++;
right++;
}
maxRight[left] = right - 1; // 以 left 开头最远可到的位置
// 移除 left 位置的字符,为下一次循环做准备
cnt[arr[left] - '0']--;
}

// 2. 前缀和数组 preSum[i] = sum_{j=0}^{i-1} (maxRight[j] - j + 1)
long[] preSum = new long[n + 1];
for (int i = 0; i < n; i++) {
preSum[i + 1] = preSum[i] + (maxRight[i] - i + 1);
}

// 3. 处理查询
long[] res = new long[queries.length];
for (int idx = 0; idx < queries.length; idx++) {
int l = queries[idx][0];
int r = queries[idx][1];

// 二分查找最后一个位置 p 满足 maxRight[p] < r
int low = l, high = r, p = l - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (maxRight[mid] < r) {
p = mid;
low = mid + 1;
} else {
high = mid - 1;
}
}

long total = 0;
if (p >= l) {
// 左端点 i ∈ [l, p],贡献 (maxRight[i] - i + 1)
total += preSum[p + 1] - preSum[l];
}
if (p + 1 <= r) {
// 左端点 i ∈ [p+1, r],贡献 (r - i + 1)
long len = r - (p + 1) + 1;
total += len * (len + 1) / 2;
}
res[idx] = total;
}
return res;
}
}
```

复杂度分析

· 时间复杂度:O(n + q log n),n 是字符串长度,q 是查询数量。
· 滑动窗口 O(n)
· 预处理前缀和 O(n)
· 每个查询二分查找 O(log n)
· 空间复杂度:O(n),存储 maxRight 和 preSum。

示例验证

```java
// 示例
String s = "000111";
int k = 1;
int[][] queries = {{0, 5}};
// 输出: [10]
// 解释: 满足 K 约束的子串有:
// "0","0","0","1","1","1","00","01","10","11" 等共10个
```

这个解法利用了滑动窗口的单调性和前缀和,在 LeetCode 上可以通过所有测试。

http://www.zskr.cn/news/1531871.html

相关文章:

  • HsMod:炉石传说55项功能全能插件,彻底改变你的游戏体验 [特殊字符]
  • 太仓市高新技术企业认定的所需材料及申报流程
  • 2026年 马鞍山颗粒板厂家推荐榜单:ENF实木颗粒板/防潮双饰面颗粒板,全屋定制优选品牌深度解析 - 品牌发掘
  • 内证观察笔记
  • 免费M3U8视频下载器终极指南:告别复杂命令行,一键下载在线视频
  • 深入解析NXP PXD10微控制器:显示控制、内存架构与系统设计实践
  • 别再只盯着Landsat和Sentinel了:这些新兴遥感数据源(如夜光、高光谱)能帮你解决什么实际问题?
  • PXD10 LCD驱动模块详解:从原理到实战配置与优化
  • MPC866 PowerPC指令集深度解析:从整数运算到原子操作与性能优化
  • Locale Remulator终极指南:彻底解决64位应用程序区域乱码问题
  • 2026年武汉白蚁高发季,如何快速联系专业消杀机构?全国多地服务现状与选择指南 - 优质品牌商家
  • 避坑指南:GROMACS后处理计算RDF和SDF时,你可能会遇到的5个典型问题
  • 终极桌游卡牌设计指南:EZCard免费批量生成器完整教程
  • QueryExcel终极指南:3分钟掌握Excel批量查询,工作效率提升10倍的秘密武器
  • 2026薛家岛街道空调拆卸对外电话及服务信息汇总 - 品牌排行榜
  • 2026年电源排插什么牌子好?这些品牌值得关注 - 品牌排行榜
  • 行业内比较好的合同诈骗罪刑辩律师有哪些 - 品牌排行榜
  • 2026年质量好的高分子防腐电缆桥架生产商口碑推荐 - 品牌排行榜
  • 2026年高温工业吸尘器十大品牌排名:Shiwosi史沃斯、TIAOZHANZ挑战者、LIRBOM厉邦推荐评测 - 工业清洁测评社
  • MuleSoft AI编排实战:企业级LLM集成与治理方法论
  • 华岐|正大|友发|振鸿|焊接钢管批发|四川盛世钢联国际贸易有限公司 - 四川盛世钢联营销中心
  • 真实无剧本探店|2026静安区黄金回收红黑榜,新手变现直接抄作业 - 沪上贵金属口碑推荐官
  • 深入解析多核DSP MSC8251:架构、优化与高密度通信应用
  • 2026年工业锅炉市场观察:西南地区主流汽锅炉厂家综合能力评估 - 优质品牌商家
  • Axios 0.21 vs 1.2:一个Content-Type配置引发的‘血案’,手把手教你如何正确设置请求头
  • MSC8251 DMA编程实战:中断管理与状态监控核心配置详解
  • 华为eNSP模拟器里,这10条BGP命令我天天用(附常用场景解析)
  • 2026年翻板坝源头厂家深度观察:技术迭代与项目落地双轮驱动行业升级 - 优质品牌商家
  • 终极修复指南:彻底解决Windows程序启动依赖问题
  • 2026拒当“大冤种”!深港跨城全屋定制真有全流程包办?第三方深度测评拆解