如何从vector<int>中移除所有出现多次的元素实例并计算剩余元素之和
解决思路:彻底移除所有重复过的元素(而非去重保留单个)
嘿,我完全懂你卡了两小时的挫败感——毕竟LeetCode的「简单」题有时候也会挖这种容易混淆的坑!你当前用的sort + unique + erase组合,核心问题是它做的是「去重(保留每个元素的一个副本)」,而题目要求的是「彻底删掉所有出现次数≥2的元素」,这俩逻辑完全不一样。
为什么你的代码不符合预期?
拿输入{1,2,2,3,4}举例:
sort后数组变成{1,2,2,3,4}unique会把连续重复的元素(第二个2)移到数组末尾,返回的迭代器指向第一个重复元素的位置,此时数组前半部分是{1,2,3,4},后半部分是多余的2erase之后剩下的就是{1,2,3,4},但题目要求是删掉所有出现过多次的元素(也就是2要完全消失),所以结果自然不对。
两种可行的解决方案
方案1:用哈希表统计次数(直观易理解)
先遍历数组统计每个元素的出现次数,再遍历一次数组,只累加那些出现次数恰好为1的元素。
#include <unordered_map> #include <vector> #include <numeric> int sumUniqueElements(std::vector<int>& nums) { std::unordered_map<int, int> countMap; // 第一步:统计每个元素的出现次数 for (int num : nums) { countMap[num]++; } // 第二步:累加只出现一次的元素 int total = 0; for (int num : nums) { if (countMap[num] == 1) { total += num; } } return total; }
- 时间复杂度:O(n),两次线性遍历
- 空间复杂度:O(n),需要哈希表存储元素次数
方案2:排序后遍历筛选(空间优化)
如果不想用额外的哈希表空间,可以先排序,然后遍历数组,找出那些前后都没有重复的元素(注意处理数组首尾的边界情况)。
#include <vector> #include <algorithm> #include <numeric> int sumUniqueElements(std::vector<int>& nums) { if (nums.empty()) return 0; std::sort(nums.begin(), nums.end()); int total = 0; int n = nums.size(); for (int i = 0; i < n; ++i) { // 第一个元素:只需要和下一个元素比较 if (i == 0) { if (nums[i] != nums[i+1]) { total += nums[i]; } } // 最后一个元素:只需要和前一个元素比较 else if (i == n-1) { if (nums[i] != nums[i-1]) { total += nums[i]; } } // 中间元素:前后都不能和当前元素相同 else { if (nums[i] != nums[i-1] && nums[i] != nums[i+1]) { total += nums[i]; } } } return total; }
- 时间复杂度:O(nlogn),主要来自排序操作
- 空间复杂度:O(1)(忽略排序算法本身的栈空间开销)
总结
你之前的思路混淆了「去重保留单个」和「移除所有重复元素」这两个完全不同的需求,只要切换到统计次数或者排序后筛选唯一元素的逻辑,就能解决问题啦!
内容的提问来源于stack exchange,提问作者L. Birkett
相关产品推荐
相关产品推荐

