算法通关手册题解:LeetCode 0722 删除注释——C++ 注释语法与双指针逐行模拟
教程文档知识库【免费下载链接】AlgoNote⛽️「算法通关手册」从零开始的「算法与数据结构」学习教程200 道「算法面试热门题目」1000 道「LeetCode 题目解析」持续更新中项目地址https://gitcode.com/gh_mirrors/le/AlgoNote点击查看免费下载本文是「算法通关手册」中 LeetCode 0722「删除注释」 题解的深入解读。题目要求删除一段 C 源码中的行注释//与块注释/* ... */并保持行结构原样返回。本文从注释语法与优先规则出发推导出基于块注释状态标志的逐字符模拟算法给出可直接运行的 Python 代码并结合复杂度分析与源码佐证帮助读者掌握这一类「跨行状态 逐行模拟」问题的通用解法。1. 题目信息与考查点题号0722LeetCode 编号完整题解位于 remove-comments.md标签数组、字符串原始文档标注难度中等输入形式source是一个字符串数组其中source[i]表示第i行源码等价于源码由\n分隔输出形式删除注释后以相同格式返回源代码数组删除后为空的字符串不输出即答案中每个字符串都非空在「算法通关手册」的 题解总览 中本题被归类为「数组、字符串」标签的中等难度题目属于字符串处理中典型的逐字符扫描与状态维护问题。2. 题目大意与注释语法规则给一个 C 程序删除程序中的注释。程序source是一个数组其中source[i]表示第i行源码每行源码由\n分隔。C 中存在两种注释风格行注释字符串//表示//及其右侧的其余字符都应被忽略块注释字符串/*表示从/*开始直到下一个非重叠出现的*/之间的所有字符都应被忽略。注意阅读顺序为从左到右「非重叠」意味着字符串/*/并不会结束块注释因为注释结尾*/与开头/*发生了重叠。规则中还明确了注释之间的优先级第一个有效注释优先于其他注释如果字符串//出现在块注释中它会被忽略不会开启新的行注释同样如果字符串/*出现在行注释或块注释中它也会被忽略。关于输入数据题目给出了明确的约束与保证1 source.length 10^30 source[i].length 80source[i]由可打印的 ASCII 字符组成每个块注释最终都会被闭合因此在行或块注释之外的/*总是开始新的注释给定的源码中不会出现单引号、双引号或其他控制字符例如source /* Not a comment. */;这类含字符串字面量的样例不会出现没有其他内容如定义或宏会干扰注释。最后一个关键特性是隐式换行符可以通过块注释删除。由于块注释可以跨越多行被块注释包裹的行间换行符也随之消失这一特性在示例 2 中体现得非常明显。3. 示例分析3.1 示例 1行注释与多行块注释共存输入: source [/*Test program */, int main(), { , // variable declaration , int a, b, c;, /* This is a test, multiline , comment for , testing */, a b c;, }] 输出: [int main(),{ , ,int a, b, c;,a b c;,}]原始代码编排如下/*Test program */ int main() { // variable declaration int a, b, c; /* This is a test multiline comment for testing */ a b c; }第 1 行的/*与第 6-9 行的/*表示块注释第 4 行的//表示行注释。删除注释后int main() { int a, b, c; a b c; }可以看到几个细节第 1 行被整个块注释删除直接不输出第 4 行// variable declaration之后的内容被忽略但行首的两个空格在//之前被保留因此输出 第 6-9 行的块注释跨 4 行删除后这几行全为空不输出输出结果与原文档给出的[int main(),{ , ,int a, b, c;,a b c;,}]完全一致。3.2 示例 2块注释吃掉换行符输入: source [a/*comment, line, more_comment*/b] 输出: [ab]原始的source字符串等价于a/*comment\nline\nmore_comment*/b。删除注释后被块注释包裹的两处换行符隐含换行符也被删除剩下的ab以换行符分隔成数组时就是[ab]。这正是「隐式换行符可以通过块注释删除」的实际体现也是本题区别于普通字符串题目的关键点块注释状态必须在行与行之间保持跨行状态。4. 解题思路基于块注释状态标志的逐字符模拟4.1 核心思想删除注释本质上是一个「逐字符扫描 状态维护」的过程。由于块注释可以跨越多行单靠逐行处理无法完成任务必须用一个跨行持久的状态标志记录当前是否处于块注释中。用状态机的视角来看整个处理过程只有两个状态正常代码状态不在块注释中此时可能遇到普通字符、/*进入块注释、//忽略本行剩余部分块注释状态此时唯一关心的是是否遇到*/退出块注释其余所有字符包括//、/*、换行一律忽略。4.2 实现步骤参照 remove-comments.md 中「思路 1模拟」的步骤使用一个标志in_block表示当前是否在块注释中遍历每一行的每个字符如果在块注释中查找*/结束块注释如果不在块注释中遇到/*进入块注释遇到//忽略该行剩余部分break否则将字符加入当前行如果当前行不为空且不在块注释中将其加入结果。这里有一个实现细节值得注意/*、//、*/都是双字符标记判断时必须同时检查i 1 len(line)防止越界并且匹配成功后下标要一次跳过两个字符i 2。4.3 为什么块注释中的//与/*会被忽略由于in_block状态为真时代码只会查找*/这一种双字符序列其余字符全部跳过因此块注释内部出现的//不会触发行注释逻辑、/*也不会嵌套开启新的块注释。这正是「第一个有效注释优先于其他注释」规则的代码级体现也符合题目保证「每个块注释最终都会被闭合」的设定。5. 完整代码实现以下代码完整继承自 remove-comments.md 的「思路 1」实现class Solution: def removeComments(self, source: List[str]) - List[str]: result [] in_block False # 是否在块注释中 current_line [] # 当前行的内容 for line in source: i 0 while i len(line): if in_block: # 在块注释中查找 */ if i 1 len(line) and line[i:i2] */: in_block False i 2 else: i 1 else: # 不在块注释中 if i 1 len(line) and line[i:i2] /*: # 进入块注释 in_block True i 2 elif i 1 len(line) and line[i:i2] //: # 行注释忽略该行剩余部分 break else: # 普通字符 current_line.append(line[i]) i 1 # 如果不在块注释中且当前行不为空加入结果 if not in_block and current_line: result.append(.join(current_line)) current_line [] return result6. 代码逐段拆解与正确性论证6.1 跨行状态变量in_blockin_block在每行循环结束后不会重置这是整个算法的灵魂。当一行以未闭合的/*结束时如示例 2 的第一行a/*comment下一行会带着in_block True继续扫描从而保证跨行块注释被完整跳过。6.2current_line的累积与冲刷current_line以字符列表形式累积普通字符避免频繁字符串拼接。每行处理完毕时若in_block True说明当前行正处在块注释内部这一行无论是空还是累积了内容理论上块注释内不会累积内容都不输出且不清空current_line若in_block False且current_line非空把当前行拼成字符串加入result并清空current_line若in_block False且current_line为空整行被注释或为空行不输出。注意current_line的清空时机只有行处理完毕且不在块注释中时才清空。如果一行以块注释开始并以块注释结束如x/*c*/y由于块注释内不会向current_line追加字符x、y会正确拼接在同一行中。6.3 双字符标记的边界判断所有双字符标记判断都带i 1 len(line)边界条件避免在行尾读取越界。匹配成功后的i 2保证不会重复消费已匹配的标记字符这是扫描类算法常见的易错点。6.4 正确性验证对照两个示例示例 1逐行执行结果输入行处理过程输出行/*Test program */第 0 位遇/*进入块注释随后遇*/退出current_line为空不输出int main()普通字符全部累积int main(){普通字符累积{// variable declaration行首两个空格累积遇//breakint a, b, c;普通字符累积int a, b, c;/* This is a test...testing */全程处于块注释状态不输出多行a b c;普通字符累积a b c;}普通字符累积}示例 2逐行执行结果输入行处理过程输出行a/*comment累积a遇/*进入块注释行末in_block True暂不输出line块注释状态整行跳过暂不输出more_comment*/b块注释状态中遇*/退出随后累积bab三行最终拼接出ab与题目输出[ab]一致验证了「块注释删除隐含换行符」的行为。7. 复杂度分析时间复杂度$O(n \times m)$其中 $n$ 是源代码的行数$m$ 是每行的平均长度。每个字符最多被访问一次两个双字符标记每次多消耗一个字符的检查仍为线性。空间复杂度$O(n \times m)$主要用于存储结果result辅助空间current_line与in_block为 $O(m)$ 与 $O(1)$。8. 思路小结一类「跨行状态模拟」题的通法本题看似是一道字符串处理题但其难点在于状态跨行块注释可以跨越多行因此单行内的正则替换或字符串分割无法正确处理。这类问题在「算法通关手册」的其他题解中也反复出现例如remove-comments.md 的姊妹题如 0727. 最小窗口子序列子串匹配同样需要在扫描中维护指针与状态手册的 04_string 章节从 字符串基础 讲起覆盖 Brute Force 朴素匹配、KMP 等字符串算法其对应的源码实现位于 codes/python/04_string/string_brute_force.py 与 codes/python/04_string/string_kmp.py读者可对照学习双指针逐字符扫描的通用技巧。解题通法总结凡是需要「根据前缀标记忽略一段文本、且标记可跨行」的题目都可以采用「持久状态标志 逐字符扫描」的框架——把跨行信息保存在状态变量中单行内只做局部判断行与行之间保持状态连续性。本题的in_block状态就是这一框架的典型实现掌握后即可迁移到其他词法扫描、注释剥离、语法高亮等场景。赞分享教程文档知识库【免费下载链接】AlgoNote⛽️「算法通关手册」从零开始的「算法与数据结构」学习教程200 道「算法面试热门题目」1000 道「LeetCode 题目解析」持续更新中项目地址https://gitcode.com/gh_mirrors/le/AlgoNote点击查看免费下载相关推荐删列造序LeetCode 0944题解AlgoNote 算法通关手册中的数组与字符串双指针模拟实战删列造序LeetCode 0944题解AlgoNote 算法通关手册中的数组与字符串双指针模拟实战 本篇题解来自「算法通关手册」AlgoNote项目教程文档知识库算法通关手册LeetCode 0006 Z 字形变换题解模拟法逐行重构与周期规律算法通关手册LeetCode 0006 Z 字形变换题解模拟法逐行重构与周期规律 Z 字形变换Zigzag Conversion是 LeetCode教程文档知识库AlgoNote 算法通关手册LeetCode 0763「划分字母区间」贪心 哈希表 双指针逐行精讲AlgoNote 算法通关手册LeetCode 0763「划分字母区间」贪心 哈希表 双指针逐行精讲 导读 本篇题解对应 AlgoNote算法通关教程文档知识库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Codex 安装与使用指南:把 auth.json 改到 TaoToken 的完整配置流程

Codex 安装与使用指南:把 auth.json 改到 TaoToken 的完整配置流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:39:58 阅读更多 →
京东农场自动化攻略:enen脚本助你轻松收获

京东农场自动化攻略:enen脚本助你轻松收获

京东农场自动化攻略:enen脚本助你轻松收获 京东农场作为深受用户喜爱的互动平台,让许多人在闲暇时间体验种植乐趣并收获实际奖励。不过手动操作往往耗费时间和精力,而enen脚本提供了高效的自动化解决方案,让你轻松管理京东农场&a…

2026/10/10 11:39:58 阅读更多 →
Rust 桌面 UI 三强横评:GPUI/Slint/egui 谁最适合生产?gpui-kit 的答案出人意料

Rust 桌面 UI 三强横评:GPUI/Slint/egui 谁最适合生产?gpui-kit 的答案出人意料

Rust 桌面 UI 三强横评:GPUI/Slint/egui 谁最适合生产?gpui-kit 的答案出人意料 【免费下载链接】gpui-kit Rust GUI components for building fantastic cross-platform desktop application by using GPUI. 项目地址: https://gitcode.com/GitHub_Tr…

2026/10/10 11:39:58 阅读更多 →

最新新闻

渐进符号与算法复杂度:从直觉到实战的完整指南

渐进符号与算法复杂度:从直觉到实战的完整指南

第一次学渐进符号的时候,我卡了挺久。倒不是定义看不懂——O、Ω、Θ三行不等式摆在那里,每个符号都认识——难的是搞不清它们到底在描述什么,也很难把f(n)O(g(n))这种写法套到实际问题上。特别是那个等号,怎么看怎么别扭&#xf…

2026/10/10 12:35:13 阅读更多 →
TraeAI Skill接入Unity完整指南:一次配置,长期生效

TraeAI Skill接入Unity完整指南:一次配置,长期生效

做Unity开发的人应该都有这种体验:项目越做越深,问AI的问题却越来越“重复”。我最近在给一个数字孪生Demo收尾,天天在TraeAI里让它帮我写C#脚本、查URP管线报错、排查粒子特效内存泄漏,但每次开口前都得先把一堆项目背景重新交代…

2026/10/10 12:35:13 阅读更多 →
Flutter CustomPainter 在 OpenHarmony 上的 2D 游戏渲染实战方案

Flutter CustomPainter 在 OpenHarmony 上的 2D 游戏渲染实战方案

CustomPainter 这个名字,玩过 Flutter 的人多少都听过,但真正把它用在游戏画面渲染上、还跑在 OpenHarmony 设备上的人,可能没那么多。这篇文章想跟你分享的就是这么一件事:用 Flutter 的 CustomPainter 在 OpenHarmony 上做一套轻…

2026/10/10 12:35:13 阅读更多 →
Skill + 连接器 + MCP 一次打包:Codex 插件组合拳怎么打

Skill + 连接器 + MCP 一次打包:Codex 插件组合拳怎么打

Skill 连接器 MCP 一次打包:Codex 插件组合拳怎么打 【免费下载链接】plugins OpenAI Plugins 项目地址: https://gitcode.com/GitHub_Trending/plugins123/plugins 如果你打开过 Codex 的插件页,大概会被那一长串名字劝退:GitHub、…

2026/10/10 12:35:13 阅读更多 →
YOLO瓶子数据集701张图像训练全流程:从数据检查到ONNX部署

YOLO瓶子数据集701张图像训练全流程:从数据检查到ONNX部署

简介:本资源为面向YOLO系列目标检测算法的瓶子数据集,适用于yolov5、yolov7、yolov8、yolov9、yolov10及yolo11等主流框架,可直接用于模型训练与验证测试,适合正在做目标检测项目、课程设计或算法对比实验的开发者与学习者。压缩包…

2026/10/10 12:35:13 阅读更多 →
GitLab安装部署全攻略:多系统与Docker实战踩坑总结

GitLab安装部署全攻略:多系统与Docker实战踩坑总结

这几年帮不同团队搭代码托管平台,GitLab安装是绕不开的一道坎。2026年这一轮新版本迭代以后,安装方式相比早期其实简化了不少,官方对主流发行版都提供了现成的软件源,但正因来源多、系统杂,反而容易在依赖、权限、端口…

2026/10/10 12:34:12 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:25 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 11:14:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →