今天开启哈希表相关内容,哈希表理论基础可见文章
LeetCode242 有效的字母异位词
题目链接:有效的字母异位词
思路
本题只涉及到26个小写字母,可以用数组做哈希表,a~z分别代表hash[0]~hash[25],初值为0。①先遍历字符串s,将对应的字母计数加到哈希表对应位置;②遍历字符串t,将对应字母计数在哈希表中减去;③遍历哈希表,若hash表中全为0这说明s与t是字母异位词,否则不是。
代码
class Solution {
public:
bool isAnagram(string s, string t) {
vector<int> hash(26, 0); //对应26个小写字母
for (int i = 0; i < s.size(); i++) {
hash[s[i] - 'a']++;
}
for (int i = 0; i < t.size(); i++) {
hash[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) {
if (hash[i] != 0)
return false;
}
return true;
}
};
复杂度
时间复杂度 O(n)
空间复杂度O(1)
Leetcode349 两个数组的交集
题目链接:两个数组的交集
思路
因问题规模限制在10000以内,还是可以用数组做哈希表,先将nums1中元素记录在哈希表,再遍历nums2元素,找到公共元素放至res,因考虑到去重,使用set容器(unordered_set),最后将res转换成vector容器返回。若不限制问题规模,哈希表也需要用到set。
代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> hash(1001, 0);
unordered_set<int> res;
int i = 0;
for (i = 0; i < nums1.size(); i++) {
hash[nums1[i]] = 1;
}
for (i = 0; i < nums2.size(); i++) {
if (hash[nums2[i]] == 1) {
res.insert(nums2[i]);
}
}
return vector<int>(res.begin(), res.end());
}
};
复杂度
时间复杂度 O(n+m),其中m是最后set转为vector
空间复杂度O(1)
Leetcode202 快乐数
题目链接:快乐数
思路
本题需要理解,一个数如果不是快乐数,则会无限循环,那么sum的值会重复出现,此时判断出需要用到哈希法。关于重复出现的证明见下图
代码
class Solution {
public:
int getsum(int n) { //按要求得出求和函数
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n = n / 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int> hash;
while (1) {
int temp = getsum(n);
if (temp == 1)
return true;
if (hash.find(temp) != hash.end()) //已出现重复的sum
return false;
n = temp;
hash.insert(temp);
}
}
};
复杂度
时间复杂度 O(logn)
空间复杂度O(logn)
Leetcode1 两数之和
题目链接:两数之和
思路
本题O(n^2)暴力解可直接得出,但是小于O(n^2)的方法还是需要思考。本题不仅要记录元素还要记录对应的数组下标,这时想到使用map(unordered_map),key为数组元素,value为数组下标。
遍历nums,若hash中已有和其相加等于target的元素,则返回两者的下标,否则将该元素插入hash中。通过描述可以看出本题还是体现了重复出现。
本题有四个重点需要理解透彻:
- 为什么会想到用哈希表
- 哈希表为什么用map
- 本题map是用来存什么的
- map中的key和value用来存什么的
代码
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hash; //<key,value>
for (int i = 0; i < nums.size(); i++) {
auto iter = hash.find(target - nums[i]);
if (iter != hash.end()) {
return {iter->second, i};
}
hash.insert(pair<int, int>(nums[i], i));
}
return {};
}
};
复杂度
时间复杂度 O(n)
空间复杂度O(n)