判断一个元素是否出现过的场景 应该第一时间想到哈希法
242.有效的字母异位词
class Solution {
public:
bool isAnagram(string s, string t) {
int arr[26] = {0};
if (s.size() != t.size())
return false;
for (int i = 0; i < s.size(); i++) {
arr[s[i] - 'a']++;
}
for (int i = 0; i < t.size(); i++) {
arr[t[i] - 'a']--;
}
for (int i = 0; i < 26; i++) {
if (arr[i] != 0)
return false;
}
return true;
}
};
349. 两个数组的交集
数组
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
int hash[1002] = {0};
for (int i = 0; i < nums1.size(); i++) {
hash[nums1[i]] = 1;
}
for (int i = 0; i < nums2.size(); i++) {
if (hash[nums2[i]] == 1) {
result_set.insert(nums2[i]);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
};
unordered_set
find(key) | 查找值为key的元素,如果找到,则返回一个指向该元素的正向迭代器;如果没找到,则返回一个与end()方法相同的迭代器 |
begin() | 返回指向容器中第一个元素的正向迭代器 |
---|---|
end() | 返回指向容器中最后一个元素之后位置的正向迭代器返回指向容器中第一个元素的正向迭代器 |
insert() | 插入一个新元素 |
count() | 计算在无序集合容器中特定元素的出现次数 |
for(int num : nums2)
for(要遍历的数据类型 遍历变量 : 遍历对象)
从nums2的int型数组中依次将值赋值给num,将num代入for语句代码块中执行
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> result_set;
unordered_set<int> num_set(nums1.begin(), nums1.end());//无序容器
for (int num : nums2) {
if (num_set.find(num) != num_set.end())
result_set.insert(num);
}
return vector<int>(result_set.begin(), result_set.end());
}
};
202. 快乐数
哈希法
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_set<int>result_set; // 若有无限循环,即有值重复出现 考虑哈希法
while (1) {
int sum = getSum(n);
if (sum == 1)
return true;
if (result_set.find(sum) !=
result_set.end()) { // find若没找到则返回end() 此式说明sum重复出现
return false;
}
else {
result_set.insert(sum); // 将sum添加到set容器中
}
n = sum;
}
}
};
快慢指针思想判断循环
“快指针” 每次走两步,“慢指针” 每次走一步,当二者相等时,即为一个循环周期。
此时,判断是不是因为 1 引起的循环,是的话就是快乐数,否则不是快乐数。
class Solution {
public:
int getSum(int n) {
int sum = 0;
while (n) {
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = n;
do{
slow = getSum(slow);
fast = getSum(fast);
fast = getSum(fast);
}while(slow != fast);//使用do..while也很巧妙
return (slow==1)?true:false;//循环有死循环 和1引起的循环 此式判断是否因1循环
}
};
1. 两数之和
map
iter
是一个迭代器,指向unordered_map
中的一个元素。iter->first
访问该元素的键(key)。iter->second
访问该元素的值(value)。
unordered_map 提供了一个方法 insert 来将键值对插入到哈希表中。insert 方法有多种重载方式,可以插入单个元素、范围内的元素,或者通过移动插入元素。map.insert(pair<int, int>(nums[i], i)); 是其中一种插入单个元素的方式,使用了 pair 来构造键值对。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> map;
for (int i = 0; i < nums.size(); i++) {
auto iter = map.find(target - nums[i]);
if (iter != map.end()) {
return {iter->second, i};
}
map.insert(pair<int, int>(nums[i], i));//是一种插入元素的方式,使用了pair来构造键值对
}
return {};
}
};
1.为什么会想到用哈希表?
哈希法适用于查询元素是否出现过,本题可查询 (target-当前元素值) 是否遍历过
2.哈希表为什么用map?
map有key,value,可以查询元素,返回下标。符合题意
3.本题map是用来存什么的?
遍历过的元素
4.map中的key和value用来存什么的?
key存元素,value为对应下标
暴力法
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] == (target - nums[j])) {
return {i, j};
}
}
}
return {};
}
};