C++实现有序数组去重时单测例正常多测例报错如何解决
现有代码存在的问题
- 下标越界访问:去重遍历的循环变量
i从0开始,第一次判断a[i-1]-a[i]==0时会访问a[-1],属于未定义行为,不同测试用例运行时会产生随机错误。 - 重复元素漏判:当检测到重复元素、将后续元素整体前移后,没有回退
i的取值,直接进入下一轮循环会跳过当前位置新移入的元素,连续多个重复值的场景下会残留重复项。 - 移动元素逻辑越界:内层循环中当
k = n-1时,a[k] = a[k+1]会访问数组边界外的a[n],触发未定义行为。 - 语法兼容性问题:
int a[n]是变长数组,不属于C++标准语法,仅部分编译器支持扩展,可能存在编译失败的风险。
修复方案
推荐使用效率更高、逻辑更安全的双指针法实现排序后去重,避免频繁移动数组元素的开销,也规避了下标越界问题,修改后代码如下:
#include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { int t; cin >> t; while (t--) { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } sort(a.begin(), a.end()); // 双指针去重逻辑 int unique_len = 1; for (int i = 1; i < n; i++) { if (a[i] != a[unique_len - 1]) { a[unique_len++] = a[i]; } } // 输出去重后的结果 for (int i = 0; i < unique_len; i++) { cout << a[i] << " "; } cout << endl; } return 0; }
如果要保留原有移动元素的逻辑,只需要调整三处即可:
- 去重循环的
i从1开始遍历 - 每次执行完元素前移操作后,执行
i--避免跳过新移入的元素 - 内层移动元素的循环上限调整为
n - 1,避免访问a[n]
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

