当前位置: 首页 > article >正文

哈希表笔记

教程来自代码随想录

哈希表笔记

什么时候使用哈希法:当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候

重点是在于如何转化查找的问题

有效的字母异位词

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}; // 默认数值为0
        for (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是找key
            if(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;
}

http://www.kler.cn/a/470060.html

相关文章:

  • C++二十三种设计模式之迭代器模式
  • UWB实操:用信号分析仪(频谱分析仪)抓取UWB频域的图像
  • 数据库1-4讲
  • 防止密码爆破debian系统
  • 级联配准learning
  • ECCV`24 | 首次解决文本到3D NeRFs分解问题!港中文等提出DreamDissector
  • 卡诺图化简最小项表达式
  • leetcode 2274. 不含特殊楼层的最大连续楼层数 中等
  • 后台运行 Python
  • JVM实战—MAT的使用和JVM优化总结
  • pip error: microsoft visual c++ 14.0 or greater is required
  • 文档解析工具:如何将PDF文档转换为Markdown格式?
  • 【FlutterDart】 listView.builder例子二(14 /100)
  • 练习(继承)
  • 25考研|重邮软件工程复试攻略!
  • 数据结构-单链表及其应用
  • 2025课题推荐:低空飞行器在复杂环境中的导航与避障系统
  • 资源分享:gpts、kaggle、paperswithcode
  • excel快速计算周数的方法
  • vue3中ref动态定义
  • 使用Llama 3.1创建合成数据集以调优你的大型语言模型
  • LeetCode代码随想录(二)——977.有序数组平方、209长度最小子数组、59螺旋矩阵2
  • Unity3D仿星露谷物语开发15之创建道具晃动效果
  • Vue——使用html2pdf插件,下载pdf文档到本地
  • VAxios
  • 深入了解 Nginx:进程、代理及用途解析