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

LeetCode 696. 计数二进制子串(详细解析 + 多解法实现)

LeetCode 696. 计数二进制子串详细解析 多解法实现前言LeetCode 696. 计数二进制子串是一道经典的字符串处理题目难度中等核心考察对字符串分组、规律提炼的能力。本题看似简单但如果暴力求解会超时因此需要找到高效的解题思路。本文将从题目分析、思路推导、代码实现基础版优化版、复杂度分析、常见坑点等方面全面拆解这道题帮你彻底吃透解题逻辑同时适配CSDN技术博客的实战风格附完整可运行代码和测试案例。适用人群算法入门者、字符串处理学习者、LeetCode刷题爱好者适合巩固字符串分组和贪心思想的应用。核心目录题目核心解析题干拆解 示例分析解题思路推导暴力法 → 优化法循序渐进代码实现Python严格遵循题干给定类结构复杂度分析时间 空间常见坑点与避坑技巧拓展思考同类题目延伸一、题目核心解析1.1 题干拆解题目给定一个仅由 ‘0’ 和 ‘1’ 组成的字符串 s要求统计满足以下两个条件的非空连续子串数量子串中 0 和 1 的数量相等子串中的所有 0 成组连续、所有 1 成组连续即不会出现 010、101 这类交叉情况。关键补充重复出现的子串不同位置需分别统计例如示例1中“01”出现两次均计入总数。1.2 示例深度分析示例1输入 s “00110011”输出 6满足条件的子串拆解“0011”0的数量21的数量2且0连续、1连续“01”从第2个0和第1个1组成0和1各1个连续分组“1100”1的数量20的数量2连续分组“10”从第2个1和第1个0组成各1个连续分组“0011”从第3个0和第3个1组成各2个连续分组“01”从第4个0和第4个1组成各1个连续分组。注意“00110011” 不满足条件因为0和1交叉出现00→11→00→11并非所有0连续、所有1连续。示例2输入 s “10101”输出 4满足条件的子串“10”第1-2位、“01”第2-3位、“10”第3-4位、“01”第4-5位均为1和0各1个且连续分组。1.3 题干隐含规律通过示例分析可提炼核心规律满足条件的子串本质是相邻两个不同字符分组的“交集”——假设相邻两组的长度分别为 m 和 n那么这两组可组成 min(m, n) 个满足条件的子串。例如“0011” 分为 [2, 2]0的长度21的长度2min(2,2)2对应子串 “01” 和 “0011”“10101” 分为 [1,1,1,1,1]相邻两组 min 均为1共4个11114。二、解题思路推导解题思路分两步先提炼字符分组长度再根据分组长度计算满足条件的子串数量。我们从暴力法入手逐步优化到最优解法理解每一步的优化逻辑。2.1 暴力法思路简单超时警告思路遍历所有可能的子串判断每个子串是否满足“0和1数量相等”且“分组连续”两个条件统计符合条件的子串个数。具体步骤遍历字符串的所有起始位置 i0 ≤ i len(s)遍历所有结束位置 ji1 ≤ j len(s)确保子串非空且长度为偶数因为0和1数量相等截取子串 s[i…j]判断是否满足① 0和1数量相等② 所有0连续、所有1连续统计符合条件的子串数量。局限性时间复杂度 O(n²)n 为字符串长度。当 n 10⁵ 时题干提示上限运算量达到 10¹⁰远超时间限制必然超时。因此暴力法仅适用于理解题目实际刷题需优化。2.2 优化法分组统计 贪心最优解法核心思路利用“相邻分组 min(m,n) 贡献子串数”的规律先将字符串按连续相同字符分组再遍历分组数组累加相邻两组的 min 值即为最终答案。具体步骤核心分组统计将字符串 s 按连续相同字符拆分记录每组的长度得到分组数组 counts。例如s “00110011” → 分组为 [2, 2, 2, 2]00→211→200→211→2s “10101” → 分组为 [1,1,1,1,1]。计算结果遍历 counts 数组对于每一个 i1 ≤ i len(counts)累加 min(counts[i-1], counts[i])总和即为满足条件的子串数量。逻辑验证结合示例1counts [2,2,2,2]遍历过程i1min(2,2)2 → 累加 2对应 “01”、“0011”i2min(2,2)2 → 累加 2对应 “10”、“1100”i3min(2,2)2 → 累加 2对应 “01”、“0011”总和2226与示例1输出一致。优势时间复杂度 O(n)仅需遍历字符串2次1次分组1次计算空间复杂度 O(n)最坏情况如字符串全为交替字符分组数组长度为n可优化至 O(1)无需存储完整分组数组仅记录前一组长度。三、代码实现Python严格遵循题干给定的类结构实现两种版本基础分组版 空间优化版附详细注释可直接复制到LeetCode提交。3.1 基础版本分组数组易理解核心先构建分组数组再累加相邻 min 值代码简洁易懂适合入门。classSolution:defcountBinarySubstrings(self,s:str)-int:# 特殊情况字符串长度为1无满足条件的子串iflen(s)2:return0# 步骤1分组统计连续字符的长度counts[]current_chars[0]# 当前连续字符current_count1# 当前连续字符的长度forcins[1:]:ifccurrent_char:# 字符相同累加长度current_count1else:# 字符不同将当前长度加入分组更新当前字符和长度counts.append(current_count)current_charc current_count1# 循环结束后将最后一组长度加入分组数组counts.append(current_count)# 步骤2遍历分组数组累加相邻两组的min值result0foriinrange(1,len(counts)):resultmin(counts[i-1],counts[i])returnresult3.2 优化版本空间O(1)高效核心无需存储完整分组数组仅记录前一组的长度prev_count遍历过程中实时计算节省空间。修正说明原错误在于初始时将prev_count设为1第一组长度导致首次字符切换时误将“第一组与自身”计算一次多算1个结果修正后prev_count初始为0避免该问题确保结果正确。classSolution:defcountBinarySubstrings(self,s:str)-int:# 特殊情况字符串长度小于2直接返回0iflen(s)2:return0result0prev_count0# 修正初始前一组长度设为0第一组无前一组不贡献结果current_chars[0]current_count1# 当前组连续字符的长度forcins[1:]:ifccurrent_char:# 字符相同当前组长度累加current_count1else:# 字符不同累加前一组和当前组的min值仅当prev_count不为0时resultmin(prev_count,current_count)# 更新前一组长度为当前组长度重置当前组prev_countcurrent_count current_charc current_count1# 循环结束后处理最后一组和前一组的min值resultmin(prev_count,current_count)returnresult3.3 测试案例验证将示例1、示例2代入代码验证结果正确性# 测试示例1s100110011print(Solution().countBinarySubstrings(s1))# 输出6修正后符合预期# 测试示例2s210101print(Solution().countBinarySubstrings(s2))# 输出4正常# 额外测试用例s3000111print(Solution().countBinarySubstrings(s3))# 输出3正常s401print(Solution().countBinarySubstrings(s4))# 输出1正常s50print(Solution().countBinarySubstrings(s5))# 输出0正常四、复杂度分析4.1 基础版本时间复杂度O(n)n 为字符串长度。遍历字符串1次完成分组遍历分组数组1次完成计算两次遍历均为 O(n)。空间复杂度O(n)最坏情况如 s “010101…”分组数组长度为n占用 O(n) 空间。4.2 优化版本时间复杂度O(n)仅遍历字符串1次实时计算结果无额外遍历。空间复杂度O(1)仅使用常数个变量prev_count、current_count、current_char、result不占用额外空间。总结优化版本在时间和空间上均为最优适合处理题干中 n10⁵ 的极端情况推荐优先使用。五、常见坑点与避坑技巧坑点1忽略“连续分组”条件误将交叉子串计入如 “010” 视为有效子串。避坑牢记“所有0连续、所有1连续”核心是“相邻分组”而非整个子串中0和1数量相等即可。坑点2循环结束后忘记将最后一组长度加入分组数组基础版本或忘记处理最后一组与前一组的min值优化版本。避坑分组统计时循环结束后必须补充最后一组的长度否则会遗漏最后一组与前一组的贡献。坑点3特殊情况未处理如字符串长度为1导致索引越界或计算错误。避坑开头添加判断若 len(s) 2直接返回0避免无效计算。坑点4暴力法超时未想到分组统计的规律。避坑遇到字符串连续字符统计类问题优先考虑“分组”思路提炼规律避免暴力遍历。六、拓展思考6.1 同类题目延伸本题的分组统计思路可迁移到以下同类题目核心都是“连续字符分组 规律提炼”LeetCode 485. 最大连续1的个数统计连续1的最大长度分组后取最大值即可LeetCode 1446. 连续字符统计字符串中连续相同字符的最大长度分组后取最大值LeetCode 1209. 删除字符串中的所有相邻重复项 II分组后删除长度≥k的分组再重构字符串。6.2 思路拓展本题的优化思路本质是“贪心”——每一步都累加当前相邻两组的贡献无需回溯符合贪心算法“局部最优→全局最优”的特点。在字符串处理中遇到“连续分组”“相邻对比”类问题均可尝试贪心思想简化计算。七、总结LeetCode 696. 计数二进制子串的核心的是“分组统计连续字符长度”通过提炼“相邻分组 min(m,n) 贡献子串数”的规律将时间复杂度从 O(n²) 优化到 O(n)空间复杂度可优化至 O(1)。解题关键先拆分字符串为连续字符分组记录每组长度累加相邻两组的 min 值即为最终答案注意处理特殊情况和循环结束后的边界问题避免遗漏。

相关文章:

LeetCode 696. 计数二进制子串(详细解析 + 多解法实现)

LeetCode 696. 计数二进制子串(详细解析 多解法实现) 前言:LeetCode 696. 计数二进制子串是一道经典的字符串处理题目,难度中等,核心考察对字符串分组、规律提炼的能力。本题看似简单,但如果暴力求解会超…...

手把手教你从零搭建Ubuntu20.04下的ROS2开发环境

1. 为什么选择Ubuntu 20.04和ROS2 机器人开发领域近年来发展迅猛,而ROS2作为第二代机器人操作系统,已经成为行业新标准。相比第一代ROS,ROS2在实时性、跨平台支持和分布式架构等方面都有显著提升。我最初接触ROS2时也经历过不少挫折&#xff…...

Unity中控系统实战:从零构建智能展厅控制中枢

1. 为什么选择Unity开发智能展厅中控系统? 第一次接触展厅中控需求时,我考虑过很多方案:传统的PLC控制、Web中控系统、甚至专门的控制软件。但最终选择Unity的原因很简单——它能完美解决三个核心痛点: 首先,跨平台特性…...

【计算机视觉入门精讲】第一站:图像处理与视觉基础

1. 图像的本质:从数学函数到像素矩阵 第一次接触计算机视觉时,最让我震撼的发现是:原来照片就是个数学函数。想象你面前有张黑白老照片,每个位置(x,y)的颜色深浅,其实就是一个函数值f(x,y)。这个函数把二维坐标映射到亮…...

2026年精选OK镜推荐榜单,三款高口碑安全品牌助您护眼新体验

在这篇文章中,我们将深入探讨OK镜的安全性以及推荐的高口碑品牌。尤其是梦戴维(Dream Vision)、小调皮和梦小新这三款品牌,通过结合用户反馈和实际评测,帮助大家更好地了解各自的特点与优势。值得一提的是,这些品牌的AP185和DV185…...

AI编程时代,人类程序员还剩下什么?驳

故障表现 发现请求集群 demo 入口时卡住,并且对应 Pod 没有新的日志输出 rootce-demo-1:~# kubectl get pods -n deepflow-otel-spring-demo -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NO…...

如何快速掌握Mermaid在线编辑器:面向技术团队的完整实践指南

如何快速掌握Mermaid在线编辑器:面向技术团队的完整实践指南 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-…...

ICCV-2025 | 同济上海AILab VLN-PE:多模态感知与物理仿真融合的具身导航新范式

1. 当机器人学会"看图说话":VLN-PE如何重新定义导航 想象一下,你正指挥一台人形机器人在陌生大楼里找会议室。传统导航系统可能需要精确的坐标输入,而VLN-PE让机器人能像人类一样,通过"往前走20米,在第…...

免费终极指南:3分钟将Windows电脑变成专业级WiFi路由器

免费终极指南:3分钟将Windows电脑变成专业级WiFi路由器 【免费下载链接】VirtualRouter Wifi Hotspot for Windows computers (Windows 7, 8.x, Server 2012 and newer!) 项目地址: https://gitcode.com/gh_mirrors/vi/VirtualRouter VirtualRouter是一款革命…...

Python开发者必看:如何用mybatis-python-wrapper轻松操作MySQL数据库

Python开发者必看:如何用mybatis-python-wrapper轻松操作MySQL数据库 在Python生态中,数据库操作一直是开发者关注的重点。虽然SQLAlchemy和Django ORM等工具已经非常成熟,但对于熟悉Java生态中MyBatis的开发者来说,能否在Python项…...

别再纠结BF16和FP16了!手把手教你为你的LLM项目选对精度格式(含PyTorch配置示例)

BF16与FP16实战指南:为你的LLM项目选择最佳精度格式 当你在深夜调试一个7B参数的LLM模型时,突然发现训练过程中频繁出现NaN值——这可能是因为选错了浮点精度格式。作为一名经历过无数次类似场景的工程师,我想分享一些从实战中总结的经验&…...

UniversalSplitScreen:为任意游戏实现分屏多人游戏的技术解析与实战指南

UniversalSplitScreen:为任意游戏实现分屏多人游戏的技术解析与实战指南 【免费下载链接】UniversalSplitScreen Split screen multiplayer for any game with multiple keyboards, mice and controllers. 项目地址: https://gitcode.com/gh_mirrors/un/Universal…...

Mac空格键的终极魔法:100+ QuickLook插件完全指南

Mac空格键的终极魔法:100 QuickLook插件完全指南 【免费下载链接】Mac-QuickLook QuickLook plugins and packages 项目地址: https://gitcode.com/gh_mirrors/ma/Mac-QuickLook 想象一下,在Mac上只需按下空格键,就能瞬间预览任何文件…...

3种方式解决本地大模型推理的Python性能瓶颈

3种方式解决本地大模型推理的Python性能瓶颈 【免费下载链接】llama-cpp-python Python bindings for llama.cpp 项目地址: https://gitcode.com/gh_mirrors/ll/llama-cpp-python 还在为本地运行大型语言模型时的性能瓶颈而苦恼吗?llama-cpp-python作为llama…...

告别复制粘贴!用Zotero+BibTeX一键搞定IEEE会议论文参考文献(Better BibTeX插件实战)

科研效率革命:ZoteroBibTeX全自动文献管理方案 在撰写学术论文时,参考文献管理往往是耗时又容易出错的一环。特别是对于需要频繁投稿IEEE会议的研究人员来说,手动复制粘贴bibtex条目、整理citation key的过程既枯燥又低效。想象一下&#xff…...

唯理科技发布用于科研和腕部数据采集训练的神经腕带

Meta近日在发布会上公布了其神经肌电腕带产品,创新的交互方式让人机交互更具想象空间。其技术原理是使用生物电芯片采集神经电位和EMG,通过算法来判断手势运动意图,这让肌电神经腕带逐渐走入更多人的视野,在未来的人机交互场景下拥…...

GHelper终极指南:5分钟掌握华硕笔记本硬件智能控制

GHelper终极指南:5分钟掌握华硕笔记本硬件智能控制 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar,…...

LDPC码实战:用Python对比比特翻转(BF)与和积(SPA)算法,谁更强?

LDPC码算法对决:Python实战比特翻转与和积译码性能全解析 在通信系统设计与优化过程中,LDPC码作为接近香农极限的高性能编码方案,其译码算法的选择直接影响系统性能与实现成本。本文将带您深入两种经典译码算法——比特翻转(BF)与和积(SPA)的…...

2026精选记事软件前五名轻松管理日常待办事项

2026年,市面上的记事软件五花八门,打开应用商店一搜,各类榜单琳琅满目,从主打极简的便签到功能全面的全能工具,让人挑得眼花缭乱。作为一名在互联网公司打拼三年的普通打工人,我每天要应对密密麻麻的工作任…...

边走边聊 Python 3.8:Chapter 5:面向对象:把生活里的“东西”变成类

Chapter 5:面向对象:把生活里的“东西”变成类 当程序变得复杂,面向对象就是你组织世界的方式。本章将带你理解类、对象、继承、多态、属性这些核心概念,并通过生活化的例子让你真正掌握 OOP 的思维方式。你会发现:当你能把生活抽象成类,你就能把复杂变简单,把混乱变秩…...

RAG的完整链路拆解:从文档切片到向量检索到LLM回答

RAG是目前最主流的破解方案:不改模型,而是在回答之前先去知识库里把相关信息捞出来,跟问题一起喂给LLM。LLM从万事通变成了带参考资料的答题者。 上篇我们搞清了一件事:LLM的知识边界就是训练数据的边界。超出这个边界它不会说不知…...

聊一聊 C# 中的闭包陷阱:foreach 循环的坑你还记得吗?诖

. GIF文件结构 相比于 WAV 文件的简单粗暴,GIF 的结构要精密得多,因为它天生是为了网络传输而设计的(包含了压缩机制)。 当我们用二进制视角观察 GIF 时,它是由一个个 数据块(Block) 组成的&…...

GLM-5.1 月卡 99 元无限 Token:是真香还是割韭菜?实测避坑指南GLM-5.1 月卡 99 元无限 Token:是真香还是割韭菜?实测避坑指南

GLM-5.1 月卡 99 元无限 Token:是真香还是割韭菜?实测避坑指南 先说结论:适合特定人群,但坑点不少,入手前必须看清条款。 最近智谱 GLM-5.1 推出了 99.9 元/月的"无限 Token"订阅方案,在开发者圈…...

VSCode插件党福音:实测阿里通义灵码的代码续写与注释生成到底有多香

VSCode插件党福音:实测阿里通义灵码的代码续写与注释生成到底有多香 作为一名每天与VSCode相伴8小时以上的全栈开发者,我一直在寻找能真正融入编码工作流的智能辅助工具。直到遇见阿里云推出的通义灵码插件,这款基于通义大模型的AI编程助手彻…...

嵌入式开发实战:为Android设备交叉编译mmc-utils工具集

1. 为什么需要交叉编译mmc-utils 在嵌入式开发中,我们经常需要与eMMC存储设备打交道。mmc-utils就是这样一套专门用于管理eMMC存储设备的实用工具集,它提供了读取extcsd、修改分区配置、设置写保护等强大功能。但问题来了——Android设备通常没有预装这些…...

OrCAD原理图打印终极指南:Instance和Occurrence模式选择对PDF标签的影响

OrCAD原理图打印终极指南:Instance和Occurrence模式选择对PDF标签的影响 在复杂电路设计中,原理图的清晰呈现与高效导航直接关系到团队协作效率与后期维护成本。作为Cadence OrCAD的核心功能之一,Instance与Occurrence模式的选择往往被工程师…...

Keyence VT5 HMI嵌入式串口通信库深度解析

1. KeyenceHMI_Lib 库深度解析:面向工业现场的嵌入式 HMI 串行通信实现1.1 工程定位与核心价值KeyenceHMI_Lib 是一个专为 Arduino 平台(基于 PlatformIO 构建环境)设计的轻量级 C 库,其唯一且明确的工程目标是:在资源…...

别再只盯着普通图了!用Python+NetworkX快速上手超图(Hypergraph)建模,搞定复杂关系分析

用PythonNetworkX解锁超图建模:从理论到复杂关系分析实战 第一次听说"超图"这个概念时,我正为一个电商推荐系统的项目头疼——传统的图结构无法准确表达用户同时浏览多个商品的行为模式。直到发现超图(Hypergraph)这种…...

3大挑战如何破解:智能工具重塑资源获取新范式

3大挑战如何破解:智能工具重塑资源获取新范式 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 在信息爆炸的数字时代,智能资源获取已成为提升工作效率的关键技能。你是否曾因频繁查找百度网盘提取码而浪…...

Glyph视觉推理快速上手:从镜像拉取到网页推理全流程

Glyph视觉推理快速上手:从镜像拉取到网页推理全流程 1. 引言:为什么选择Glyph视觉推理 想象一下,你需要处理一本几百页的小说内容,传统的大模型需要消耗大量显存来存储这些文本的token信息。而Glyph视觉推理模型提供了一种全新的…...