力扣2315题 解题思路和步骤 C++实现带注释,c++题库编程题
问题描述与关键点分析
力扣2315题要求统计字符串中星号()的数量,但需排除被竖线(|)包围区间内的星号。输入"l|eet|co|de|"应返回2,因为第一个和一个星号位于竖线区间外。该问题的核心在于准确识别竖线配对形成的封闭区间,这需要设计状态标志位来跟踪当前是否处于有效统计区域。
潜在语义关键词包括"字符串解析"、"区间排除"和"状态标记"。解题时需特别注意连续竖线的处理,如"||"中星号应被统计,因为竖线未形成有效区间。扩展词"双指针"在此场景下可优化遍历效率,但更优解是采用单次扫描配合布尔标志位。
算法设计与状态机模型
建立is_countable布尔变量作为状态机标志,初始为true表示可统计星号。当遇到竖线时翻转状态,直到再次遇到竖线。这种设计完美匹配题目要求的区间排除逻辑,且无需存储竖线位置,空间复杂度降至O(1)。
在C++实现中,采用基于范围的for循环遍历字符串,比传统索引访问更不易出错。每次迭代时,当前字符为星号且is_countable为true时递增计数器。竖线处理需注意边界条件——当字符串以竖线开头时,首个竖线应立即触发状态切换。
代码实现与注释解析
int countAsterisks(string s) { int count = 0; bool countable = true; // 状态标志位 for(char c : s) { if(c == '|') countable = !countable; // 遇到竖线切换状态 else if(c == '' && countable) count++; // 仅统计有效星号 } return count; }
边界条件与特殊测试用例
空字符串输入应返回0,代码中默认初始化count=0已涵盖此情况。当字符串全为星号如""时,需返回字符串长度;全为竖线如"||||"则应返回0。这些边界条件在力扣测试集中均有体现。
特殊案例包括连续竖线("a||bc"中星号有效)和首尾竖线("|abc|def"仅统计第二个星号)。扩展词"测试覆盖"要求编写单元测试时需包含这些场景,gtest框架可添加EXPECT_EQ(countAsterisks("||||"), 1)的断言验证。
性能优化与替代方案
原始解法已是最优时间复杂度,但可通过位运算进一步优化:用整型替代布尔变量减少分支预测失败。修改为int flag = 1,遇到竖线执行flag ^= 1,星号统计条件改为(c == '' && flag)。
替代方案如双指针法,记录竖线位置后计算区间外星号,但需要O(k)空间存储竖线索引(k为竖线对数)。在力扣环境字符串长度≤1000的约束下,原始单次扫描法在代码简洁性和执行效率上均为最佳选择。
力扣2315题的解题核心在于建立状态机模型准确识别有效统计区间。本文提供的C++实现通过布尔标志位高效处理竖线配对,代码注释详细说明了状态切换逻辑与边界条件处理。该解法在时间/空间复杂度上均达到理论下限,适用于所有合法输入场景,可作为字符串处理类问题的标准范式。
原创内容 转载请注明出处