😲示例
主要使用map和set, 如果是键值对结构就使用map, 如果不是键值对结构但是需要去重, 就使用set
unordered_set是C++标准库中的一个容器,用于存储唯一的元素集合,所以需要去重的数据可以用它来存, 元素的存储顺序是无序的。下面是unordered_set的基本用法、常见函数和遍历方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
   |  #include <unordered_set>
 
 
  std::unordered_set<int> mySet;  std::unordered_set<int> mySet = {1, 2, 3};  std::vector<int> vec = {1, 2, 3, 4, 5}; std::unordered_set<int> mySet(vec.begin(), vec.end());  std::unordered_set<int> mySet1 = {1, 2, 3}; std::unordered_set<int> mySet2(mySet1); 
 
 
  mySet.insert(4);  mySet.insert({5, 6, 7}); 
 
 
  mySet.erase(3);  mySet.clear(); 
 
 
  auto it = mySet.find(2); 
  if (it != mySet.end()) {      } else {      }
 
 
  if (mySet.count(3) > 0) {      } else {      }
 
 
  int size = mySet.size(); 
 
 
  for (auto it = mySet.begin(); it != mySet.end(); ++it) {      }
 
  for (const auto& element : mySet) {      }
 CPP 
  | 
 
unordered_map的用法和常用函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | #include <iostream> #include <unordered_map>
  int main() {          std::unordered_map<int, std::string> myMap;
           myMap.insert({1, "apple"});     myMap[2,"orange"];     
           std::cout << "Value at key 2: " << myMap[2] << std::endl;
           if (myMap.count(2) > 0) {         std::cout << "Key 2 exists" << std::endl;     }
           auto it = myMap.find(2);     if (it != myMap.end()) {         std::cout << "Key 2 found. Value: " << it->second << std::endl;     } else {         std::cout << "Key 2 not found." << std::endl;     }
           myMap[1] = "grape";
           myMap.erase(2);
           for (const auto& pair : myMap) {         std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;     }
      return 0; }
 CPP 
  | 
 
注意使用了两种查找auto, auto it = myMap.find(2);返回的是迭代器指针, 如果需要成员变量需要使用->, 而const auto& pair : myMap使用了迭代器的引用类型, 使用指针初始化引用类型, 引用类型的使用和原变量一样, 直接使用.
 🤔一些疑问解答
 const auto& pair : myMap中必须加const吗?
在遍历unordered_map时,使用const auto& pair : myMap是一种常见的做法,但并不是必须的
使用const auto&可以确保你不会意外地修改unordered_map中的元素。这是一种安全的做法
如果需要再遍历的过程中修改或删除一些值, 那么可以使用auto&而不是const auto&
 为什么有的哈希表题目并没有用哈希表来做而是用数组?
如果题目中确实需要查每个元素, 但是元素的取值范围并不大, 而且索引可以直接算出来不需要遍历, 那么就可以直接用数组, 比如力扣题目242
 💪力扣刷题
 242. 有效的字母异位词
力扣传送门
这个需要一个哈希表记录所有字母的出现次数, 但是由于题目中只出现26个字母, 所以也可以直接使用数组记录字母出现次数
如果s中出现字母, 则再记录表中+1, 如果t表中出现字母, 则再记录表中-1, 最后只需要记录表中有没有非0元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | class Solution { public:     bool isAnagram(string s, string t) {         int letter[26] = {0};         for(int i=0; i<s.size(); i++)             letter[s[i]-'a']++;         for(int i=0; i<t.size(); i++)             letter[t[i]-'a']--;         for(int i=0; i<26; i++)             if(letter[i]!=0)                 return false;         return true;      } };
 CPP 
  | 
 
 349. 两个数组的交集
力扣传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | class Solution { public:     vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {                  unordered_set<int> data(nums1.begin(),nums1.end());                  unordered_set<int> rs;         int len = nums2.size();                  for(int i=0; i<len; i++){             if(data.find(nums2[i])!=data.end())                 rs.insert(nums2[i]);         }                  return vector<int>(rs.begin(),rs.end());     } };
 CPP 
  | 
 
 202. 快乐数
力扣传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | class Solution { public:     bool isHappy(int n) {         int new_n=n, sum;                    unordered_set<int> sums;             while(new_n!=1){                         int k;                               sum = 0;                             while(new_n!=0){                         k = new_n%10;                 sum+=k*k;                 new_n/=10;             }             if(sums.find(sum)!=sums.end())                   return false;                            else                                             sums.insert(sum);             new_n = sum;                             }         return true;                             } };
 CPP 
  | 
 
 1. 两数之和
力扣传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | class Solution { public:     vector<int> twoSum(vector<int>& nums, int target) {         vector<int> rs(2);                       unordered_map<int,int> my_map;           int len = nums.size();                   for(int i=0; i<len; i++)                     my_map[nums[i]] = i;                 for(int i=0; i<len; i++){                    auto it = my_map.find(target-nums[i]);               if(it!=my_map.end() && it->second!=i){                   rs[0] = i;                                           rs[1] = it->second;                                  break;                                           }         }         return rs;;                                      } };
 CPP 
  | 
 
 454. 四数相加 II
力扣传送门
先统计前两个数组的所有和, 用map, 键是和, 值是和出现的次数
再统计后两个数组的所有和, 不用新建map, 直接查之前的那个map里有没有相反数, 有的话结果就加上对应的情况数目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | class Solution { public:     int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {         unordered_map<int,int> my_map;         for(int i:nums1){             for(int j:nums2){                 my_map[i+j]++;             }         }         int count = 0;         for(int i:nums3){             for(int j:nums4){                 if(my_map.find(0-i-j)!=my_map.end()){                     count+=my_map[0-i-j];                 }             }         }         return count;     } };
 CPP 
  | 
 
 383. 赎金信
力扣传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | class Solution { public:     bool canConstruct(string ransomNote, string magazine) {         int letter[26] = {0};         for(char i:magazine)             letter[i-'a']++;         for(char i:ransomNote)             letter[i-'a']--;         for(int i:letter)             if(i<0)                 return false;         return true;     } };
 CPP 
  | 
 
 15. 三数之和
力扣传送门