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

Leecode刷题C语言之统计重新排列后包含另一个字符串的子字符串数目②

执行结果:通过

执行用时和内存消耗如下:

 

 

 

void update(int *diff, int c, int add, int *cnt) {diff[c] += add;if (add == 1 && diff[c] == 0) {// 表明 diff[c] 由 -1 变为 0(*cnt)--;} else if (add == -1 && diff[c] == -1) {// 表明 diff[c] 由 0 变为 -1(*cnt)++;}
}long long validSubstringCount(char* word1, char* word2) {int diff[26] = {0};for (const char *c = word2; *c; c++) {diff[*c - 'a']--;}int cnt = 0;for (int i = 0; i < 26; i++) {if (diff[i] < 0) {cnt++;}}long long res = 0;int l = 0, r = 0;int len1 = strlen(word1);while (l < len1) {while (r < len1 && cnt > 0) {update(diff, word1[r] - 'a', 1, &cnt);r++;}if (cnt == 0) {res += len1 - r + 1;}update(diff, word1[l] - 'a', -1, &cnt);l++;}return res;
}

解题思路:

这段代码的主要思路是为了解决一个特定的问题:给定两个字符串 word1 和 word2,计算 word1 中有多少个不同的子串可以通过将 word2 中的一些字符恰好替换为其他字符(不限制替换成什么字符)而得到。这里的关键在于理解 word2 中的字符可以被移除(通过替换为任意其他字符),但不能被添加。

以下是代码的详细思路:

  1. 初始化差异数组
    • 创建一个长度为 26 的数组 diff 来记录 word2 中每个字母相对于 word1 可能需要移除的数量。数组下标对应字母的 ASCII 码减去 'a' 的 ASCII 码,这样 diff[0] 对应 'a'diff[25] 对应 'z'
    • 遍历 word2,对于每个字符,将其在 diff 数组中对应位置的计数减一,表示这个字符在 word2 中存在,但在转换过程中可能需要被移除。
  2. 计算初始负差异计数
    • 遍历 diff 数组,统计所有负值的数量,存储在变量 cnt 中。这个数量表示 word2 中相对于 word1 多余的字符数量,这些字符在转换过程中必须被移除。
  3. 使用滑动窗口在 word1 中寻找有效子串
    • 初始化左右指针 l 和 r,以及结果变量 res
    • 使用一个循环,左指针 l 从字符串开始遍历到结束。
    • 在内层循环中,右指针 r 从当前 l 的位置开始向右移动,同时更新 diff 数组和 cnt,直到 cnt 为 0。这一步是通过 update 函数实现的,每次移动右指针时,将对应字符的差异加一(表示尝试将该字符包含在子串中),如果之前该字符的差异是 -1(表示需要从 word2 中移除该字符才能匹配),则这次加一操作会使差异变为 0,意味着该字符不再需要被移除,因此 cnt 减一。
    • 当 cnt 为 0 时,表示当前窗口内的字符集合可以通过移除 word2 中的一些字符(不需要添加字符)来匹配,因此所有以当前左指针 l 开头的子串都是有效的。计算这些有效子串的数量并加到 res 上。
    • 然后,左指针 l 向右移动一位,同时更新 diff 数组和 cnt,这次是将左指针指向的字符的差异减一(表示尝试将该字符从子串中移除),如果之前该字符的差异是 0(表示该字符在 word2 中没有对应字符需要移除,但现在因为左指针的移动,该字符变成了需要被移除的字符),则这次减一操作会使差异变为 -1,意味着需要移除的字符数量增加,因此 cnt 加一。
  4. 返回结果
    • 循环结束后,返回累计的有效子串数量 res
http://www.lryc.cn/news/521201.html

相关文章:

  • HTML和CSS相关的问题,为什么页面加载速度慢?
  • LiveGBS流媒体平台GB/T28181常见问题-没有收到视频流播放时候提示none rtp data receive未收到摄像头推流如何处理?
  • Flask表单处理与验证
  • 正泰电工携手图扑:变电站数字孪生巡检平台
  • 瑞芯微 RK 系列 RK3588 使用 ffmpeg-rockchip 实现 MPP 视频硬件编解码-代码版
  • uniapp 预加载分包,减少loading
  • c#删除文件和目录到回收站
  • GESP2024年12月认证C++六级( 第三部分编程题(1)树上游走)
  • Redis数据结构服务器
  • 【向量数据库 Milvus】centos8源码安装和部署 Milvus 2.5.3
  • MySQL数据库(SQL分类)
  • C++实现设计模式---原型模式 (Prototype)
  • 鸿蒙面试 2025-01-10
  • Linux Top 命令 load average 指标解读
  • 31_搭建Redis分片集群
  • 客户案例 | Ansys与索尼半导体解决方案公司合作推进自动驾驶汽车基于场景的感知测试
  • c#-Halcon入门教程——标定
  • MC1.12.2 macOS高清修复OptiFine运行崩溃
  • 精选2款.NET开源的博客系统
  • 转运机器人在物流仓储行业的优势特点
  • 简识MySQL的InnoDB Locking锁的分类
  • 如何通过openssl生成.crt和.key
  • .NetCore 使用 NPOI 读取带有图片的excel数据
  • linux上使用update-alternatives来选择软件版本
  • 【Elasticsearch复合查询】
  • Java List去重:Stream、HashMap与TreeSet对比分析
  • 大师课程:专业角色AE+AI动画动态设计关键帧学院视频课程 Key Frame Academy – Character Animation Launchpad
  • 游戏盾SDK如何防护APP攻击
  • Spring Boot 3.x 整合 Logback 日志框架(支持异步写入)
  • 从0开始学习搭网站第二天