提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
迈入哈希表
一、有效的字母异位词
1.本题set不适用,map过于麻烦
2.使用数组简单易懂,只需继续s中每个字母出现次数,再减去t中字母次数,如果数组值不为0,则不是字母异位词
class Solution {
public:
bool isAnagram(string s, string t) {
//判断一个元素是否出现在集合中,首先想到哈希表
//set不能用,一个字母可能出现多次,map过于麻烦,因此使用数组
int num[26] = {0};
//遍历s,记录字母次数
for (int i = 0; i < s.size(); i++) {
num[s[i] - 'a']++;
}
//遍历t,减去num
for (int j = 0; j < t.size(); j++) {
num[t[j] - 'a']--;
}
//遍历num,如果有不等于0,则不是
for (int i = 0; i < 26; i++) {
if (num[i] != 0) return false;
}
return true;
}
};
二、 两个数组的交集
1. 暴力解法,使用数组,将两个数组中的元素出现次数相加,如果大于1则为交集,但要控制数组每个元素只能相加一次
2. 哈希set,每个元素在set中只能出现一次,忽略暴力控制条件,更简单
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
//输出结果唯一,数组也可以,使用set更方便
//num1数组放入set中
unordered_set<int>res1(nums1.begin(), nums1.end());
unordered_set<int>res2;
for (int i = 0; i < nums2.size(); i++) {
if (res1.find(nums2[i]) != res1.end()) {
res2.insert(nums2[i]);
}
}
return vector<int>(res2.begin(), res2.end());
}
};
三、快乐数
1.刚开始没有思路,后面看了讲解才懂无限循环可能会出现重复元素,因此使用哈希set
2.有了终止条件(无限循环),循环遍历即可
class Solution {
public:
int sqNum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
//无限循环,可能会重复出现
unordered_set<int>record;
while(1) {
int sum = sqNum(n);
if (sum == 1) return true;
if (record.find(sum) != record.end()) {
return false;
}
else {
record.insert(sum);
}
n = sum;
}
}
};
四、两数之和
1. 暴力解法,两层循环
2. set只有关键字,不能存储value,选用map。同时哈希查找的是key,也就是map的第一项,因此下标存为value
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
//1.暴力解法
//2.使用map
unordered_map<int, int>record;
for (int i = 0; i < nums.size(); i++) {
if (record.find(target - nums[i]) != record.end()) {
return {i, record.find(target - nums[i])->second};
}
else {
record.insert(make_pair(nums[i], i));
}
}
return {};
}
};
总结
题目不算太难,但有些细节问题还要注意。加油!继续努力!
学习时间90min。
学习资料:《代码随想录》。