You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用vector时反复触发std::out_of_range异常的技术求助

问题分析与解决

异常原因

你遇到的std::out_of_range异常核心是越界访问vector元素,同时循环逻辑存在明显错误:

  1. 循环条件k != nums.size() + 1完全不合理,当k走到nums.size()时,nums.at(k)和nums.at(k+1)都会访问超出vector合法范围的位置(vector有效索引是0到nums.size()-1)。
  2. 即使k没到末尾,当k = nums.size()-1时,k+1 = nums.size(),此时nums.at(k+1)直接触发越界异常。
  3. 删除元素后仍自增k:erase会让vector长度减小,后续元素自动前移,这时候自增k会跳过原本要检查的元素,甚至继续触发越界。

修正后的基础版代码

void removeDuplicates(vector<int>& nums) {
    int k = 0;
    // 循环条件保证k+1始终是合法索引
    while (k < nums.size() - 1) {
        if (nums[k] == nums[k + 1]) {
            // 删除当前重复元素,后续元素前移,k不递增,继续检查当前位置
            nums.erase(nums.begin() + k);
        } else {
            // 元素不重复,移动到下一个位置
            ++k;
        }
    }
}

关键修改说明

  • 循环条件改为k < nums.size() - 1:从根源上保证每次访问nums[k+1]都在合法范围内,避免越界。
  • 删除元素后不递增k:erase操作会把后续元素往前移一位,原来的k+1位置元素现在到了k位置,需要继续检查这个新元素是否和下一个重复。
  • 去掉冗余迭代器变量:直接用nums.begin() + k作为erase的参数,简化代码。

更高效的双指针写法

基础版因为多次调用erase(每次erase是O(n)复杂度),整体时间复杂度为O(n²)。如果处理大数据量,推荐用双指针法将时间复杂度优化到O(n):

void removeDuplicates(vector<int>& nums) {
    if (nums.empty()) return;
    int slow = 0;
    for (int fast = 1; fast < nums.size(); ++fast) {
        // 找到不同元素时,慢指针移动并赋值
        if (nums[fast] != nums[slow]) {
            nums[++slow] = nums[fast];
        }
    }
    // 最后删除慢指针之后的所有重复元素
    nums.erase(nums.begin() + slow + 1, nums.end());
}

内容的提问来源于stack exchange,提问作者Gleb Bespalov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:15:13