C++集允许重复?
我试图从 leet 代码中解决面试问题,以从整数向量中删除重复项。
以下是我的答案代码:
#include <vector>
#include <set>
using namespace std;
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
vector<int>::iterator itr;
set<int> temp;
for (itr = nums.begin(); itr != nums.end(); itr++) {
if (temp.insert(*itr).second == false) {
nums.erase(itr);
}
}
return nums.size();
}
};
我添加了包含以完成。
我遇到的问题是,如果我有一个输入向量 [0,0,1,1,2,2,3,3,4,4,5,5] 我的函数只会删除重复的不是 1 或 2。
因此,我的答案将是 [0,1,1,2,2,3,4,5]。我的理解是 set 不允许重复值,但我不明白为什么 1 和 2 仍然重复。
回答
这是因为这是未定义的行为。
nums.erase(itr);
std::vector's erase() 方法使所有现有迭代器“在擦除点或之后”无效。由于itr是“擦除点”,返回itr时不再是有效的迭代器erase()。后续尝试增加它,在for循环的迭代中会导致未定义的行为。
您的 C++ 教科书将更完整地解释如何使用erase()返回的值及其含义,以便正确避免未定义的行为;但胶囊总结是:
itr=nums.erase(itr);
请注意,现在itr指向在向量的值后已经是什么erase()d,这可能是end(); 不管是end()不是你显然不想立即增加它。很明显,您想检查向量中紧随其后的值是否也是另一个重复值,您不同意吗?
所以你需要稍微修改一下,loop以便它:
-
erase()正确使用 -
仅在迭代器没有
erase()重复值时才增加它。