● 哈希表理论基础
反正有了它复杂度就能够降低
哈希碰撞
拉链法和线性探测法
拉链法:选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
线性探测法:使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。
例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize ,要不然哈希表上就没有空置的位置来存放 冲突的数据了。
三种哈希结构:
数组
set (集合)
map(映射)
● 242.有效的字母异位词
就是判断两个字符串所用字母是否相同,相同true,不相同false
一种思路是直接用sort对字符串进行排序,直接对得到的两个字符串对比就可以。
class Solution {
public:
bool isAnagram(string s, string t) {
sort(s.begin(),s.end());
sort(t.begin(),t.end());
if(s==t)
return true;
else
return false;
}
};
还有一个思路就是设置一个数组,比如说record[26]={0},然后对对于一个字符串在它字母所对应的ASCII码上进行计数,比如record[ASCII],然后这个位置上的数就能够记录这个字符串上有多少个这样的字母。对于字符串1是++,字符串2是- -,然后只需要判断整个record数组是否为零。
class Solution {
public:
bool isAnagram(string s, string t) {
int record[26]={0};
for(int i=0;i<s.size();i++)
{
record[s[i]-'a']++;
}
for(int i=0;i<t.size();i++)
{
record[t[i]-'a']--;
}
for(int i=0;i<26;i++)
{
if(record[i]!=0)
return flase;
}
return true;
}
};
● 349. 两个数组的交集
一开始的思路就是建立一个新数组,遍历题中的两个数组后,如果两个数组出现重叠的部分,将该元素存进新数组中。不过存储之前需要对这个新数组进行循环防止出现重复的元素,比如说[1,2,2,1]和[2,2]只需要输出一个2就可以了。
【标准答案】
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set; // 用的是set里面最下边的那个哈希表。这个哈希表是用来存放结果的,之所以用set是为了给结果集去重
unordered_set<int> nums_set(nums1.begin(), nums1.end());//nums_set 是一个无序集合,它包含了 nums1 容器中的所有不重复的整数元素。
for (int num : nums2) {
// 发现nums2的元素 在nums_set里又出现过
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
//这段代码是在遍历 nums2 容器中的元素,并检查每个元素是否也存在于 nums_set 无序集合中。如果某个元素在 nums_set 中存在,就将它插入到 result_set 中。
//具体的执行过程如下:
//对于 nums2 容器中的每个元素 num,进行遍历。
//使用 nums_set.find(num) 来查找 num 是否存在于 nums_set 中。如果存在,find 函数将返回一个指向该元素的迭代器;如果不存在,将返回一个指向 nums_set.end() 的迭代器。
//如果 num 存在于 nums_set 中(即 find 函数返回的迭代器不等于 nums_set.end()),则将 num 插入到 result_set 中。
//最终,result_set 将包含 nums2 中存在于 nums1 的元素,并且这些元素将按照插入的顺序存储在 result_set 中。
return vector<int>(result_set.begin(), result_set.end());
}
};
自己重新写了一遍,但觉还是不太熟悉,可能是对这些能够直接调用的函数不熟吧,目前就了解一个大概思路。
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int>result_set;
unordered_set<int>nums_set(nums1.begin(),nums1.end());
for(int num:nums2)//对于数组nums2中的每个元素,将其赋值给变量num,然后执行循环体中的代码
{
if(nums_set.find(num)!=num_set.end)//nums_set.end() 并不是集合中的元素,而是用于标识集合的结束位置的特殊迭代器值。在使用无序集合进行迭代时,通常会使用循环来遍历集合中的元素,而结束迭代器则用于判断循环是否达到了集合的末尾。
{
result_set.insert(num);
}
}
return vector<int>(result_set.begin(),result_set.end());
}
};
● 202. 快乐数
原理懂了还不是很会用
● 1. 两数之和
之前做过,但是也忘了,过两天再补吧