繁体   English   中英

c++ 中的无序 map

[英]Unordered map in c++

我正在尝试使用unordered map在 C++ 中实现此问题:

给定一个非空整数数组,每个元素都出现两次,除了一个。 找到那个单一的。

笔记:

您的算法应该具有线性运行时复杂度。 您能否在不使用额外的 memory 的情况下实现它?

示例 1:

输入:[2,2,1]
Output:1

示例 2:

输入:[4,1,2,1,2]
Output:4

我的解决方案:

class Solution {
 public:
  int singleNumber(vector<int>& nums) {
    std::unordered_map<int, int> umap;

    for (auto i = nums.begin(); i != nums.end(); i++) {
      umap[*i] = umap[*i] + 1;
    }

    for (auto i = umap.begin(); i != umap.end(); i++) {
      if (umap[*i] == 1) {
        return *i;
      }
    } 
  }
};

但不幸的是,它不起作用。 编译时出现此错误

Line 16: Char 17: fatal error: no viable overloaded operator[] for type 'std::unordered_map'
        if (umap[*i] == 1) {
            ~~~~^~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/unordered_map.h:973:7: note: candidate function not viable: no known conversion from 'std::pair' to 'const std::unordered_map, std::equal_to, std::allocator > >::key_type' (aka 'const int') for 1st argument
      operator[](const key_type& __k)
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/unordered_map.h:977:7: note: candidate function not viable: no known conversion from 'std::pair' to 'std::unordered_map, std::equal_to, std::allocator > >::key_type' (aka 'int') for 1st argument
      operator[](key_type&& __k)
      ^
1 error generated.

我无法理解错误。 谁能给我解释一下?

错误的相关位是:

candidate function not viable: no known conversion from
   'std::pair' to
   'const std::unordered_map, std::equal_to, std::allocator > >::key_type'
       (aka 'const int')
for 1st argument operator[](const key_type& __k)

所以这意味着当在umap[*i] == 1中使用下标运算符时, * *i的类型是一些std::pair并且运算符期望的类型是const int (查看“aka”)。

这是因为 map 迭代器返回一个std::pair包含对键数据值数据的引用。 您可以仅从迭代器轻松获取值数据,而无需调用下标运算符:

if (i->second == 1)
  return i->first;

但是,正如评论中所述,您不需要任何额外的容器来解决这个难题。 约束“你能在不使用额外的 memory 的情况下实现它吗?” 实际上是对解决方案的提示。 在非空整数数组中有一个数学属性,其中每个元素出现两次(.),除了一个。


另外,我建议使用变量名i作为索引并调用迭代器it ,但这只是个人喜好。

您不需要std::unordered_map因为std::unordered_set在这种情况下就足够了:

std::unordered_set<int> set;
for( auto i : nums ) {
   auto p = set.insert( i );
   if( !p.second ) set.erase( p.first );
}

因此,逻辑是您尝试插入一个数字,但如果它已经存在,则将其删除。 除了更小的 memory 占用空间之外,这种方法的另一个好处是,在循环之后,您将在集合中只有一个元素 - 您需要一个。 所以你不需要迭代和搜索。

但是正确的解决方案是您应该注意的技巧。 它基于xor或运算的性质:

A xor A == 0 for any A
A xor 0 == A for any A

并且因为xor操作也具有可交换性:

A xor B xor A == A xor A xor B == 0 xor B == B

我认为您现在无需额外的 memory 即可获得实现的想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM