贝利信息

c++中如何删除数组中的重复元素_c++数组去重实现

日期:2026-01-22 00:00 / 作者:冰火之心
首选 std::unordered_set 辅助去重以获得无重复副本,时间复杂度低且代码简洁;原地去重则用双指针法,O(n) 时间、O(1) 空间,需手动 resize。

std::setstd::unordered_set 辅助去重(适合原始数组不可变)

如果只是需要一份无重复的副本,且不关心原数组顺序是否保留,最稳妥的做法是借助标准容器自动去重。注意:std::set 会排序,std::unordered_set 保持插入顺序但需类型支持哈希。

std::vector nums = {1, 2, 2, 3, 3, 4};
std::unordered_set seen;
std::vector unique;
for (int x : nums) {
    if (seen.insert(x).second) { // insert 返回 pair,second 为 true 表示新插入
        unique.push_back(x);
    }
}

原地去重:用双指针法处理 std::vector

这是最常用也最高效的原地去重方式,时间复杂度 O(n),空间 O(1),但要求元素可比较(如 ==),且只保留首次出现的元素。

std::vector v = {1, 2, 2, 3, 2, 4};
if (v.empty()) return;
size_t i = 0;
for (size_t j = 1; j < v.size(); ++j) {
    if (v[j] != v[i]) {
        v[++i] = v[j];
    }
}
v.resize(i + 1); // 关键:不 resize 就只是前 i+1 个有效

std::unique + erase 组合(仅适用于已排序数组)

std::unique 不是真的删除元素,它把重复项移到末尾并返回新尾迭代器。必须配合 erase 才算完成去重,而且只对相邻重复有效 —— 换句话说,数组必须先排序。

std::vector v = {3, 1, 2, 1, 3, 2};
std::sort(v.begin(), v.end()); // 必须先排
auto last = std::unique(v.begin(), v.end());
v.erase(last, v.end());

处理 C 风格数组时的常见陷阱

很多人卡在“怎么对 int arr[10] 去重”,根本问题是:C 数组没有长度元信息,函数无法知道边界,传参必须显式带长度,且无法安全缩容。

// 正确传参方式
int removeDuplicates(int arr[], int n) {
    if (n == 0) return 0;
    int i = 0;
    for (int j = 1; j < n; ++j) {
        if (arr[j] != 

arr[i]) { arr[++i] = arr[j]; } } return i + 1; // 新长度 } // 调用方需记录返回值:int new_len = removeDuplicates(arr, 10);
裸数组去重没有银弹,关键在分清“要不要改原数组”“数组是否已排序”“能不能换容器”。用错 std::unique 或忽略 resize 是高频失误点。