问题描述
我已经尝试解决一个“简单”的 leetcode 问题两个小时了,我需要删除出现不止一次的 int 的每个实例,然后将非重复项添加在一起。我已经尝试了大约 10 种不同的方法,但我只能将其归结为每个 int 的一个副本。这是我写的最好的解决方案,但给定输入 {1,2,3,4} 它将返回 {1,4} 而预期的输出是 {1,4}>
sort(nums.begin(),nums.end()); //Sort numerically
nums.erase(unique(nums.begin(),nums.end()),nums.end());
return (accumulate(nums.begin(),nums.end(),0));
解决方法
NlogN
复杂性,您无需预先排序:
#include <set>
#include <vector>
int main()
{
std::vector<int> nums = {1,5};
std::multiset<int> m (nums.begin(),nums.end());
std::size_t sum = 0;
for (const auto& elem : m)
{
sum += m.count(elem) == 1 ? elem : 0;
}
}
更新:可以使用 std::unordered_multiset
,因为我们不需要订购。
您可以使用 std::unordered_map<int,bool>
,其中第二个(模板)参数 (bool
) 指定值是否重复。它看起来像这样,
#include <unordered_map>
...
std::unordered_map<int,bool> uniqueCheckMap;
for (auto i : nums)
{
if (uniqueCheckMap.find(i) == uniqueCheckMap.end())
uniqueCheckMap[i] = false;
else
uniqueCheckMap[i] = true; // Set the second (value) as true if duplicate entry is found.
}
nums.clear();
int sum = 0;
for (auto i : uniqueCheckMap)
{
if (!i.second)
{
nums.push_back(i.first);
sum += i.first;
}
}
,
有很多解决方法,您可以遍历数组并使用 map
或其他方法查看该数字存在多少次,然后再次遍历地图并将仅出现一次的数字添加到新的大批。
您可以使用集合和 map<bool,int>
,每次添加新数字时,您都会检查它是否存在。
if(!map[number]){
set.insert(number);
map[number]=true;
}else{
set.erase(number);
}
,
如果 O(n²) 不是问题...
const auto sum=std::accumulate(cbegin(nums),cend(nums),[&](const auto &accum,const auto &elem)
{
return accum+(std::count(cbegin(nums),elem)>1 ? 0 : elem);
});
,
set_difference
在这里很有帮助。它会按照您描述的方式删除出现的情况。
auto ints = vector{4,1};
sort(begin(ints),end(ints));
std::vector<int> unique_ints;
unique_copy(begin(ints),end(ints),back_inserter(unique_ints));
vector<int> doubles;
set_difference( begin(ints),begin(unique_ints),end(unique_ints),back_inserter(doubles)
);
vector<int> only_once;
set_difference( begin(unique_ints),begin(doubles),end(doubles),back_inserter(only_once));
copy(begin(only_once),end(only_once),ostream_iterator<int>(cout,","));
cout << "\n";
还有……它似乎可以解决问题。
$ g++ -std=c++17 u.cpp && ./a.out
1,4,
,
或者您可以在“相等范围”上使用循环,只累积单个元素长的那些:
sort(begin(ints),end(ints));
int acc = 0;
auto range = equal_range(begin(ints),ints.front());
while(range.first != end(ints)) {
cout << *range.first << "+ ";
if (distance(range.first,range.second) == 1){
acc += *range.first;
}
range = equal_range(range.second,*range.second);
}
cout << " = " << acc << "\n";