LeetCode行星碰撞题中std::out_of_range异常原因排查求助
解决vector越界问题:行星碰撞代码分析
错误原因分析
1. 并列if导致的无效索引访问
你的代码中处理行星碰撞的三个if是并列关系而非else if,这意味着即使第一个if已经修改了vector的大小和left/right指针,后面的两个if仍然会执行,此时访问asteroids.at(left)或asteroids.at(right)会触发越界。
举个具体场景:
假设初始asteroids = [5, -5, 3],left=0,right=2:
- 进入第一个分支判断左右行星方向相反,且
abs(5) == abs(-5)成立:- 先执行
erase(right=2),vector变为[5, -5],size=2; - 再执行
erase(left=0),vector变为[-5],size=1; - 更新
left=1,right=1。
- 先执行
- 代码继续执行后面的两个
if,尝试访问asteroids.at(1),但当前vector的有效索引只有0,直接触发std::out_of_range异常。
2. 循环逻辑的死循环隐患(附加问题)
当左右行星方向相同、不会碰撞时,代码没有移动left和right指针,会导致循环一直卡在同一位置,无法终止。
修复方案
将三个处理碰撞的if改为else if结构,确保每次只执行一个分支,同时添加else分支处理不会碰撞的情况:
class Solution { public: vector<int> asteroidCollision(vector<int>& asteroids) { auto left = 0; auto right = asteroids.size() - 1; while (left <= right) { if (left == right) { return asteroids; } bool willCollide = (asteroids.at(left) > 0 && asteroids.at(right) < 0) || (asteroids.at(left) < 0 && asteroids.at(right) > 0); if (willCollide) { if (abs(asteroids.at(left)) == abs(asteroids.at(right))) { asteroids.erase(asteroids.begin() + right); asteroids.erase(asteroids.begin() + left); left++; right--; } else if (abs(asteroids.at(left)) > abs(asteroids.at(right))) { asteroids.erase(asteroids.begin() + right); right--; } else { asteroids.erase(asteroids.begin() + left); left++; } } else { // 无碰撞风险,移动指针 left++; right--; } } return asteroids; } };
内容的提问来源于stack exchange,提问作者Petr Máša
相关产品推荐
相关产品推荐

