如何修复LeetCode 1047题C++代码的无符号偏移量溢出运行时错误
问题排查与修复方案
错误原因分析
- 越界访问内存:核心问题出在
while (s[i-count]==s[i+1+count])这个循环条件——没有做边界检查。当count递增到i-count < 0或者i+1+count >= s.length()时,会访问字符串的非法内存区域,触发未定义行为,这正是LeetCode报错的直接原因。 - 类型不匹配导致逻辑混乱:
s.length()返回无符号类型size_t,而循环变量i是有符号的int。当i -= count后变成负数时,和size_t类型比较时,负数会被转换为超大的无符号值,导致循环条件失效,可能提前终止或进入异常流程。 - erase操作参数非法:当
i+1超出字符串长度,或者2*count大于从i+1到字符串末尾的字符数时,s.erase()会触发非法内存操作。
修复方案
方案一:修正原有代码逻辑(适配对称重复场景)
如果要保留你原有的对称重复检测逻辑,需要添加严格的边界检查,并调整循环变量的控制:
string removeDuplicates(string s) { int n = s.size(); for (int i = 0; i < n; ) { // 手动控制i的递增,避免自动递增导致的遗漏 int count = 0; // 添加强制边界检查,确保索引合法 while (i - count >= 0 && i + 1 + count < n && s[i - count] == s[i + 1 + count]) { count++; } if (count > 0) { int start = i - count + 1; int len = 2 * count; s.erase(start, len); n = s.size(); // 更新字符串长度 i = start - 1; // 回退到删除位置前,检查新产生的相邻重复 } else { i++; // 无重复则正常前进 } } return s; }
注意:这个逻辑主要处理对称型相邻重复(如abba),不完全匹配原题中"连续相邻重复"的要求(如aabb需要完全删除为空)。
方案二:栈结构标准解法(完全符合题目要求)
栈是解决这类相邻重复移除问题的最优方案,逻辑简洁且高效:
string removeDuplicates(string s) { string res; for (char c : s) { if (!res.empty() && res.back() == c) { res.pop_back(); // 遇到相邻重复,移除末尾字符 } else { res.push_back(c); // 无重复则加入结果 } } return res; }
这个逻辑的核心是用字符串模拟栈:遍历原字符串,每次将当前字符与结果字符串的最后一位对比,若相同则弹出末尾(消除重复),否则加入当前字符。最终结果就是所有相邻重复都被移除后的字符串,完全满足题目要求,时间复杂度O(n),空间复杂度O(n)(若允许修改原字符串,还可以优化到O(1)空间)。
内容的提问来源于stack exchange,提问作者Arsh
相关产品推荐
相关产品推荐

