最近在LeetCode刷题,又撞上了溢出错误这个老冤家。那次做一道数组相关的题目,代码在本地IDE里跑得飞快,所有测试用例都通过,可一提交到平台就报错。盯着屏幕半天,才意识到是整数溢出的锅——两个大数相加,结果超出了int的范围,变成了负数。这种错误藏得深,尤其在算法竞赛中,稍不注意就功亏一篑。
溢出错误分两类:整数溢出和内存溢出。整数溢出常见于变量计算,比如int类型上限是2147483647,你再加1就变成-2147483648,程序逻辑直接崩掉。内存溢出则是数组越界或缓冲区问题,比如访问array时数组只有5个元素,轻则数据错乱,重则程序崩溃。在LeetCode上,测试用例往往设计边界值,像n=0或n=1000000,一不小心就触发溢出。
调试这些错误需要点技巧。我习惯从边界测试入手,先跑极端输入:最小值、最大值、空值。如果代码在n=1000000时崩了,立刻检查循环索引或累加变量。另一个实用方法是加打印语句,在关键步骤输出变量值。比如,在累加前打印当前sum,看它何时超限。调试器工具如GDB或IDE内置的debugger也帮大忙,设置断点追踪变量变化。
内存优化是预防溢出的关键。核心是减少不必要的分配和访问。在C++里,用vector.reserve()预分配内存,避免动态扩容的开销;Java中,少在循环里new对象,改用静态或复用结构。数据结构选择也重要——如果键值范围大,优先HashMap而非数组;动态规划题中,用滚动数组优化空间,从O(n^2)降到O(n)。
实际刷题时,我常遇到这类陷阱。比如一道字符串处理题,我用了int存储字符计数,结果输入超长字符串时计数溢出。改成long类型就解决。优化后,内存占用降了,运行时间也缩短。细节决定成败,多练多反思,代码自然更健壮。
|