第2周 第1天 力扣刷题|有效的字母异位词、两个数组的交集、快乐树和两数之和

哈希表

关于set和map的一些知识

官方解释:哈希表是根据关键码的值来直接进行访问的数据结构

干什么用:快速判断一个函数是否出现在集合里

数组其实就是一张哈希表

红黑树是一种平衡二叉搜索树,key值是有序的,所以不能修改 -> 只能删除和增加

当使用集合来解决哈希问题时,优先使用 unordered_set 因为它的查询和增删效率是最优的

如果要求集合是有序的,则使用 set ;否则,使用 multiset

multiset的成员函数

 iterator find(const T &val); // 在容器中查找值为val的元素,返回其迭代器;若找不到,返回end()
 iterator insert(const T &val); // 将val插入到容器中并返回其迭代器
 void insert(iterator first, iteratorlast); // 将[first, last)插入容器
 int count(const T &val); // 返回值为val的元素个数
 iterator lower_bound(const T &val); // 查找一个最大的位置it,使得[begin(), it)中所有元素都比val小
 iterator upper_bound(const T &val); // 查找一个最小的位置it,使得[it, end())中所有元素都比it大
 iterator erase(iterator it); // 删除it指向的元素,返回其后面的元素的迭代器 

有效的字母异位词

题目:力扣

思路:由于只有小写字母,所以可以建立一个元素个数为26的数组,数组中的val来存放相应字母出现的次数,'a'出现的次数放在数组下标为0的位置,'b'出现的次数放在数组下标为1的位置,依次类推,依次遍历string s,在相应的数组下标位置val++,就可以得到一个数组,数组下标0~25的位置分别存放string s中字母a~z出现的次数;接着可以遍历string a,与前面相反的是,遍历string t,在相应的数组下标位置val--。最后,如果数组不为空,说明两个stirng不同,否则相同。

 class Solution {
 public:
     bool isAnagram(string s, string t) {
         int slen = s.size();
         int tlen = t.size();
         int record[26] = {0};
         for (int i = 0; i < slen; i++)
         {
             record[s[i] - 'a']++;
         }
         for (int j = 0; j < tlen; j++)
         {
             record[t[j] - 'a']--;
         }
         for (int k = 0; k < 26; k++)
         {
             if (record[k] != 0)
                 return false;
         }
         return true;
     }
 };

两个数组的交集

题目:力扣

思路:首先创建一个集合nums1_set,把第一个数组nums1的值放进去(会自动去重),然后定义一个集合result_set,用来存放在两个数组中均出现的元素。遍历nums2中的元素,首先判断该元素是否在num1_set1中出现过,如果出现过,将该元素查到result_set,如果没出现过就不管,进入下一次循环,知道遍历完nums。最后将result_set的结果放到一个vector中返回即可。

 class Solution {
 public:
     vector intersection(vector& nums1, vector& nums2) {
         unordered_set result_set; // 定义一个set对象,用来存放结果;
         unordered_set nums1_set(nums1.begin(), nums1.end()); // 将num1中的值放到set中
         for (int num : nums2)
         {
             if (nums1_set.find(num) != nums1_set.end()) // 如果在nums1_set中找不到,会返回num1_set.end();
                 result_set.insert(num);
         }
         vector result(result_set.begin(), result_set.end());
         return result;
     }
 };

快乐树

题目:力扣

思路:首先写一个函数getSum,来求一个数的各个位数上数的平方和。创建一个集合result_set,用来存放每次循环时数的各个位数上数的平方和,在循环过程中,我们需要判断集合中是否存放当前循环对应的数的存在,如果不存在的话将这个平方和插入result_set中,否则,直接返回false。

 class Solution {
 public:
     int getSum(int n) // 用来求一个数的各个位数上数的平方和
     {
         int sum = 0;
         while (n)
         {
             int k = n % 10; // 此时n为个位对应的数
             sum += k * k;
             n /= 10;
         }
         return sum;
     }
 ​
     bool isHappy(int n) {
         unordered_set result_set;
         while (true)
         {
             int sum = getSum(n);
             if (sum == 1)
                 return true;
             if (result_set.find(sum) == result_set.end()) // 为真说明不存在
             {
                 result_set.insert(sum);
                 n = sum;
             }
             else
                 return false;
         }
     }
 };

两数之和

题目:力扣

 class Solution {
 public:
     vector twoSum(vector& nums, int target) {
         unordered_map map;
         for (int i = 0; i < nums.size(); i++)
         {
             unordered_map::iterator it = map.find(target - nums[i]);
             if (it != map.end()) // 说明找到了
             {
                 vector result = {it->second, i};
                 return result;
             }
             map.insert(pair(nums[i], i)); 
         }
         return {};   
     }
 };

你可能感兴趣的:(笔记,leetcode,哈希算法,散列表)