教程来自代码随想录
哈希表笔记
什么时候使用哈希法:当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候
重点是在于如何转化查找的问题
有效的字母异位词
leetcode242
用对应++和–判断
bool isAnagram(string s, string t) {if(s.length()!=t.length()) return false;unordered_map<char,int> comp;for(int i=0;i<s.length();i++){comp[s[i]]++;}for(int i=0;i<t.length();i++){if(comp[t[i]])comp[t[i]]--;else return false;}return true;}
bool isAnagram(string s, string t) {int record[26] = {0};for (int i = 0; i < s.size(); i++) {// 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了record[s[i] - 'a']++;}for (int i = 0; i < t.size(); i++) {record[t[i] - 'a']--;}for (int i = 0; i < 26; i++) {if (record[i] != 0) {// record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。return false;}}// record数组所有元素都为零0,说明字符串s和t是字母异位词return true;}
赎金信(字母交集)
bool canConstruct(string ransomNote, string magazine) {unordered_map<char,int> hashmap;for(char text:magazine){hashmap[text]++;}for(char need:ransomNote){if(hashmap[need])hashmap[need]--;else return false;}return true;}
两个数组交集
leetcode349
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> s1;unordered_set<int> num2(nums2.begin(),nums2.end());for(int i=0;i<nums1.size();i++){if(num2.find(nums1[i])!=num2.end()){s1.insert(nums1[i]);}}return vector<int>(s1.begin(),s1.end());}
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重int hash[1005] = {0}; // 默认数值为0for (int num : nums1) { // nums1中出现的字母在hash数组中做记录hash[num] = 1;}for (int num : nums2) { // nums2中出现话,result记录if (hash[num] == 1) {result_set.insert(num);}}return vector<int>(result_set.begin(), result_set.end());}
快乐数(无限循环的本质是出现重复值)
unordered_set可以用来辅助查重
int getsum(int n){int sum=0;while(n){sum+=(n%10)*(n%10);n=(n-(n%10))/10;}return sum;}bool isHappy(int n) {unordered_set<int> repeat;while(1){int sum=getsum(n);if(sum==1)return true;else {n=sum;if(repeat.find(sum)!=repeat.end()){return false;}repeat.insert(sum);}}}
查找数组中是否有两数之和等于目标值
可以查找target-num1
vector<int> twoSum(vector<int>& nums, int target) {int answer1,answer2;unordered_map<int,int> num;for(int i=0;i<nums.size();i++){auto iter=num.find(target-nums[i]); //find是找keyif(iter!=num.end()){answer1=i;answer2=iter->second;break;}num[nums[i]]=i;}return vector<int>({answer1,answer2});}
四数相加
关键是组好key和value
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {//关键点是想清楚key放什么,value放什么//key放a+b的值,value放值出现的次数unordered_map<int,int> hashmap;for(int a:nums1){for(int b:nums2){hashmap[a+b]++;}}int count=0;for(int c:nums3){for(int d:nums4){if(hashmap[0-c-d]){count+=hashmap[0-c-d];}}}return count;}
查找出现k次的字符
作业题
给定一个ASCII字符串,查找字符串中,出现了k次的字符。比如,字符串"This is a good day!"中,出现了2次的字符为’a’,‘d’,‘i’,‘o’, ‘s’,出现了4次的字符为’ '。
INPUT
2
This is a good day! 2
This is a good day! 4
OUTPUT
'a','d','i','o','s'
' '
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include<queue>
#include <algorithm>using namespace std;
struct Compare{bool operator()(char a,char b){return a>b;}
};
int main(){unordered_map<char,int> textset;int n;cin>>n;getchar();while(n--){int count;string s;getline(cin,s);//cout<<s<<endl;if(s[s.size()-1]>='0'&&s[s.size()-1]<='9'){count=s[s.size()-1]-'0'; s=s.substr(0,s.size()-2);}else{continue;}unordered_map<char,int> hashmap;for(char ch:s){hashmap[ch]++;}//找k个,加入集里priority_queue<char,vector<char>,Compare> result;for(auto pair:hashmap){if(pair.second==count){result.push(pair.first);}}//打印if (!result.empty()) {while (!result.empty()) {char r=result.top();cout << '\'' << r << '\'';result.pop();if (!result.empty()) cout << ',';}cout << endl;} else {cout << endl;}}
}
有重复的元素查询(查询第k次出现的元素)
作业题
给出一个整数序列,请找出一个整数v的第k次出现(从左到右)在序列中的位置。为了增加题目的挑战性,请回答m个这样的查询。
INPUT
20 4
1 3 2 2 4 3 2 1 9 2 4 2 1 2 6 5 3 2 1 4
9 1
4 5
2 4
3 3
OUTPUT
9
0
10
17
哈希表用int-vector的格式
key是元素的值,vector存的是出现的所有位置
int main() {int n, m;while (cin >> n >> m) {unordered_map<int, vector<int>> hashmap;for (int i = 0; i < n; ++i) {int number;cin >> number;hashmap[number].push_back(i + 1); // Store position as 1-indexed}for (int i = 0; i < m; ++i) {int v, k;cin >> v >> k;auto it = hashmap.find(v);if (it != hashmap.end() && it->second.size() >= k) {cout << it->second[k - 1] << endl; // Convert back to 1-indexed} else {cout << "0" << endl;}}}return 0;
}