一、知识点介绍
哈希表
1. 介绍
unordered_map是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能
2. 特性
- 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)
- 无序性:使用hash表存储,内部无序
- Map : 每个值对应一个键值
- 键唯一性:不存在两个元素的键一样
- 动态内存管理:使用内存管理模型来动态管理所需要的内存空间
3. 迭代器
- unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值。
1 unordered_map<Key,T>::iterator it;
2 (*it).first; // the key value (of type Key)
3 (*it).second; // the mapped value (of type T)
4 (*it); // the "element value" (of type pair<const Key,T>)
- 它的键值分别是迭代器的first和second属性。
1 it->first; // same as (*it).first (the key value)
2 it->second; // same as (*it).second (the mapped value)
二、练习题目
(1) 442. 数组中重复的数据
(2) 2068. 检查两个字符串是否几乎相等
(3) 2283. 判断一个数的数字计数是否等于数位的值
(4) 884. 两句话中的不常见单词
三、算法思路
1. 数组中重复的数据
(1) 用一个哈希表存入每个数字出现的次数;
(2)再遍历哈希表,出现两次的元素存入答案数组并返回。
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int hash[100010];
memset(hash, 0, sizeof(hash));
int i;
vector<int> ans;
for(i = 0; i < nums.size(); ++i) {
++hash[nums[i]];
}
for(i = 0; i < 100010; ++i) {
if(hash[i] == 2) {
ans.push_back(i);
}
}
return ans;
}
};
2. 检查两个字符串是否几乎相等
(1) 用两个哈希表存入每个字符串字母出现的次数;
(2)再判断这两个哈希表是否相同;相同就返回true,否则就返回false。
class Solution {
int code(char c) {
return c - 'a';
}
public:
bool checkAlmostEquivalent(string word1, string word2) {
bool ans = false;
int hash1[26];
int hash2[26];
memset(hash1, 0, sizeof(hash1));
memset(hash2, 0, sizeof(hash2));
int i;
for(i = 0; i < word1.size(); ++i) {
++hash1[code(word1[i])];
}
for(i = 0; i < word2.size(); ++i) {
++hash2[code(word2[i])];
}
for(i = 0; i < 26; ++i) {
if(abs(hash1[i]-hash2[i]) <= 3) ans = true;
else {
ans = false;
break;
}
}
return ans;
}
};
3. 判断一个数的数字计数是否等于数位的值
(1) 首先需要写一个方法把字符串转换成数字。
(2) 再把每一次数字出现的次数存入一个哈希表中;
(3) 再按照题意判断哈希表中对应的次数和数字是否相等,如果相等返回true;否则返回false。
class Solution {
int code(char c) {
return c - '0';
}
public:
bool digitCount(string num) {
int hash[10];
memset(hash, 0, sizeof(hash));
bool ans;
int i;
for(i = 0; i < num.size(); ++i) {
++hash[code(num[i])];
}
for(i = 0; i < num.size(); ++i) {
if(code(num[i]) == hash[i]) ans = true;
else {
ans = false;
break;
}
}
return ans;
}
};
4. 两句话中的不常见单词
(1) 首先先拼接两个字符串;
(2) 再通过空格判断每个单词,并把每个单词存入哈希map中,统计出现的次数;
(3) 如果只出现一次的话,就存入答案数组中并返回。
class Solution {
unordered_map<string, int> hash;
public:
vector<string> uncommonFromSentences(string s1, string s2) {
s1 += " ";
s1 += s2;
s1 += " ";
int i;
char temp[420];
int size = 0;
vector<string> ans;
for(i = 0; i < s1.size(); ++i) {
if(s1[i] == ' ') {
temp[size] = '\0';
if(size) {
hash[temp]++;
}
size = 0;
} else {
temp[size++] = s1[i];
}
}
for(auto iter = hash.begin(); iter != hash.end(); ++iter) {
if(hash[iter->first] == 1) {
ans.push_back(iter->first);
}
}
return ans;
}
};