簡體   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