六月集训(第07天)—哈希表
哈希表
1. 442. 数组中重复的数据
思路1:
首先是开空间为$O(n)$的数组空间,建立hash映射。
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
bool hash[100001];
memset(hash, 0, sizeof(hash));
vector<int> ans;
int nums_size = nums.size(), i;
for (i = 0; i < nums_size; ++i) {
if (!hash[nums[i]]) hash[nums[i]] = 1;
else ans.push_back(nums[i]);
}
return ans;
}
};
思路2:
将空间优化为$O(1)$
利用nums[]本身作为hash表,nums[i]出现一次,将其作为下标对应的值取反(标记出现了)idx = abs(nums[i]),如果nums[idx]是负的,则idx出现两次,将idx加入答案。
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> ans;
int nums_size = nums.size(), i;
nums.push_back(1);
for (i = 0; i < nums_size; ++i) {
int idx = abs(nums[i]);
if (nums[idx] > 0) nums[idx] = -nums[idx];
else ans.push_back(idx);
}
return ans;
}
};
2. 2068. 检查两个字符串是否几乎相等
思路:
利用hash记录每个字母出现的次数,对于word1,每出现一次,记录+1;word2中字母每出现一次,hash-1,最后如果有某个字母的出现次数的绝对值大于3,则不满足;否则满足。
class Solution {
public:
bool checkAlmostEquivalent(string word1, string word2) {
int hash[26];
memset(hash, 0, sizeof(hash));
int word1_len = word1.length();
int word2_len = word2.length();
int i;
for (i = 0; i < word1_len; ++i) {
hash[word1[i] - 'a']++;
}
for (i = 0; i < word2_len; ++i) {
hash[word2[i] - 'a']--;
}
for (i = 0; i < 26; ++i) {
if (hash[i] > 3 || hash[i] < -3) return false;
}
return true;
}
};
3. 2283. 判断一个数的数字计数是否等于数位的值
思路:
记录每个值出现的次数,与对应的数字应该出现的次数进行比对,不满足则返回false,否则返回true。
class Solution {
public:
bool digitCount(string num) {
int hash[11];
memset(hash, 0, sizeof(hash));
int num_len = num.length(), i;
for (i = 0; i < num_len; ++i) {
hash[ num[i] - '0' ]++;
if (hash[i] > num[i] - '0') return false; /* 优化一下,如果某个数字出现的次数已经超出了对应的限制,则不满足 */
}
for (i = 0; i < num_len; ++i) {
if (hash[i] != num[i] - '0') return false;
}
return true;
}
};
4. 884. 两句话中的不常见单词
先尝试自己写,遇到两个难点:
1. hash映射函数:想了半天没想到合适的hash映射关系,最后想到利用每个字母在单词的第几位,就乘上几作为加权。
2. 如何统计两个字符串中只出现一次,而在另一个中没有出现,代码越写越像shi山。最后一看英雄哥将两个字符串拼起来,统计只出现一次的单词,直呼妙不可言。
C++的map函数太香了,学一手迭代器的使用。此时此刻我只想说STL NB!
思路:
将两字符串拼接,建立hash映射,记录每个单词出现的次数,将只出现一次的单词作为答案。
class Solution {
public:
vector<string> uncommonFromSentences(string s1, string s2) {
unordered_map<string, int> hash;
string temp = "";
vector<string> ans;
// 将两字符串拼接
s1 += " ";
s1 += s2;
s1 += " ";
// 利用哈希表,记录每个单词出现的次数
int s_len = s1.length(), i;
for (i = 0; i < s_len; ++i) {
if (s1[i] == ' ') {
hash[temp]++;
temp = "";
} else {
temp += s1[i];
}
}
// 取出只出现一次的单词作为答案
for (auto iter = hash.begin(); iter != hash.end(); ++iter) {
if (iter->second == 1) ans.push_back(iter->first);
}
return ans;
}
};
东方欲晓,莫道君行早。

浙公网安备 33010602011771号