【基础算法训练】—— 哈希表

简介: 【基础算法训练】—— 哈希表

知识铺垫——真的分得清哈希表吗


什么是哈希表


简单的来说,哈希表是一种表结构,我们可以直接根据给定的key值计算出目标位置。通常是采用数组实现了

与普通的列表不同的地方在于,普通列表仅能通过下标来获取目标位置的值,而哈希表可以根据给定的key计算得到目标位置的值。

在列表查找中,使用最广泛的二分查找算法,复杂度为O(log2n),但其始终只能用于有序列表。普通无序列表只能采用遍历查找,复杂度为O(n)。而拥有较为理想的哈希函数实现的哈希表,对其任意元素的查找速度始终为常数级,即O(1)。


下面浅看一下官方对哈希表的描述吧。

C++里一般不直接使用这个库函数的,只是这种映射的思想比较重要,很多时候咱们数组模拟的哈希表其实也就是实现这个思想。


假如想手动实现核心的散列函数,这儿有两种比较常用的方式,可以作为积累,但是现在很少手动实现了吧

一、拉链法

image.png二、开放寻址法

微信图片_20221019203926.png

set 和 unordered_set

微信图片_20221019204050.png


map 和 unordered_map


微信图片_20221019204117.png

set 和 map的区别

微信图片_20221019204150.png


第一题 1512. 好数对的数目


哈希表+组合数学


题目描述

微信图片_20221019204254.png

解题报告


看到这种数据范围,啊,拿出可爱的暴力


题目让咱们求的是组合的情况,题目要求i < j这个条件我感觉可以忽视吧,只要有数列中有个相同的数字,就直接可以组合成数对了,大不了在书写的时候,写成i < j的模式。

让咱们求相同的数,两两组合的情况,比如现在有4个相同的数(样例二),

两两组合的情况是C 4 2 C_{4}^2C 42= 4 * (4-1) / 2 = 6,符号样例二的输出结果

其他的相同数字两两组合的情况,也可以使用类似的方式计算出来的,在计算之前,咱们只是需要使用哈希表来统计数列中每个数出现的次数。


参考代码(C++版本)


解法一

class Solution {
public:
    int numIdenticalPairs(vector<int>& nums) {
        int n = nums.size();
        int ans = 0;
        for(int i = 0; i < n;i++)
            for(int j = i+1;j < n;j++)
            {
                if(nums[i] == nums[j] && i < j) 
                    ans ++;
            }
        return ans;
    }
};

解法二:

class Solution {
public:
    int numIdenticalPairs(vector<int>& nums) {
        //哈希表+组合数学
        int cnt[110];
        memset(cnt,0,sizeof(cnt));
        int n = nums.size();
        //统计给的数列中,每个数出现的情况
        for(int i = 0; i < n;i++)
            cnt[nums[i]] ++;
        int ans = 0;
        for(int i = 0; i < 110;i++)
        //如果统计到某个数的个数至少有两个,那么就可以进行组合
        //比如有三个1,组合的情况就是(3*2)/2 = 3
            if(cnt[i] > 1)
            {
                ans += cnt[i]*(cnt[i]-1) / 2;
            }
        return ans;
    }
};

第二题 2006. 差的绝对值为 K 的数对数目


题目描述

微信图片_20221019204444.jpg

解题报告


题目的意思是去查找某个结果的时候,哈希表O(1)的时间复杂度或者二分O(logN)时间复杂度就可以多留意一下了。


对于本题而言,其实是让我们去统计满足要求的数字的个数,那咱们就可以使用一个哈希表,在将各个数值出现的次数统计出来的同时,按照题目要求的|nums[i] - nums[j]| = k,计算满足要求的数值的个数。

题目给的限制是|nums[i] - nums[j]| = k

将绝对值展开了,可以得到两个式子:

nums[i] = nums[j] + k

nums[i] = nums[j] - k

那咱们其实可以使用j作为下标从左到右遍历,统计是否有满足条件的i,倘若有就把其个数进行统计。


参考代码(C++版本)


解法一

class Solution {
public:
    int countKDifference(vector<int>& nums, int k) {
        int ans = 0, n = nums.size();
        for (int i = 0; i < n; ++i) 
            for (int j = i + 1; j < n; ++j) 
                if (abs(nums[i] - nums[j]) == k) ans ++;
        return ans;
    }
};

解法二:

class Solution {
public:
    int countKDifference(vector<int>& nums, int k) {
        unordered_map<int,int>h;
        int ans=0;
        int n = nums.size();
        for(int j = 0;j < n;j++)
        {
            h[nums[j]] ++;
            ans += h[nums[j] + k];
            ans += h[nums[j] - k];
        }
        return ans;
    }
};

第三题 1347. 制造字母异位词的最小步骤数


题目描述

image.jpeg

解题报告


题目其实就是想要咱们求,将t字符串中的字母变成和s字符串中相同的字母(不论位置),最少需要变换几个字符。

这个思路就很直接了吧,直接使用哈希表统计两个字符串中各个字母出现的情况,然后统计对于某个字符而言,t字符串中比s字符串中多的数量,这个多出来的部分,就是需要进行变换的数量。


参考代码(C++版本)

class Solution {
public:
    int minSteps(string s, string t) {
        //直接将两个字符串哈希,然后统计不同的字符的个数就是答案
        int n1 = s.size();
        int cnts[26],cntt[26];
        memset(cnts,0,sizeof(cnts));
        memset(cntt,0,sizeof(cntt));
        for(int i = 0; i < n1;i++)
        {
            cntt[t[i] - 'a'] ++;
            cnts[s[i] - 'a'] ++;
        }
        int ans = 0;
        for(int i = 0; i < 26;i++)
            if(cnts[i] < cntt[i]) ans += cntt[i] - cnts[i];
        return ans;
    }   
};

第四题 面试题 10.02. 变位词组


排序+常规情况的变型


题目描述

微信图片_20221019204729.png

解题报告


好家伙,数据范围都不放呢

这个题应该是属于小变型吧,之前咱们接触是映射字符,统计数量,比如将asdffdska存到哈希表unordered_map<char,int>中,其效果统计对应的字符的数量,字符a的数量是两个,字符d的数量是1个。

对于这个题而言了,是使用 unordered_map<string,vector<string>>统计相同字符串的不同形式,比如字符串aei的不同形式eia、aie等等。最本质的想法是一个的


参考代码(C++版本)

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        //其本质来说了,有点换汤不换药,因为之前统计的时候
        //可以用哈希表统计某个相同的字母出现的次数
        //这里了,统计某个相同的字符串
        vector<vector<string>> ans;
        unordered_map<string,vector<string>> mp;
        int n = strs.size();
        for(int i = 0; i < n;i++)
        {
            string str = strs[i];
            //对取出的字符串进行排序
            sort(str.begin(),str.end());
            //把相同的字符串加入到哈希表中
            mp[str].push_back(strs[i]);
        }
        //遍历这个哈希表统计结果,这里需要使用迭代器进行遍历了
        //倘若手写是这种的
        // unordered_map<string,vector<string>> :: iterator it;
        //倘若偷懒,是直接循环里放auto。遇事不决,我用auto...
        for(auto it = mp.begin(); it != mp.end(); it++)
            ans.push_back(it->second);
        return ans;
    }
};

总结


总结了,哈希表和字符串是好朋友

目录
打赏
0
0
0
0
9
分享
相关文章
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
探究‘公司禁用 U 盘’背后的哈希表算法与 Java 实现
在数字化办公时代,信息安全至关重要。许多公司采取“禁用U盘”策略,利用哈希表算法高效管理外接设备的接入权限。哈希表通过哈希函数将设备标识映射到数组索引,快速判断U盘是否授权。例如,公司预先将允许的U盘标识存入哈希表,新设备接入时迅速验证,未授权则禁止传输并报警。这有效防止恶意软件和数据泄露,保障企业信息安全。 代码示例展示了如何用Java实现简单的哈希表,模拟公司U盘管控场景。哈希表不仅用于设备管理,还在文件索引、用户权限等多方面助力信息安全防线的构建,为企业数字化进程保驾护航。
员工行为监控软件中的 Go 语言哈希表算法:理论、实现与分析
当代企业管理体系中,员工行为监控软件已逐步成为维护企业信息安全、提升工作效能的关键工具。这类软件能够实时记录员工操作行为,为企业管理者提供数据驱动的决策依据。其核心支撑技术在于数据结构与算法的精妙运用。本文聚焦于 Go 语言中的哈希表算法,深入探究其在员工行为监控软件中的应用逻辑与实现机制。
39 14
基于 Python 哈希表算法的局域网网络监控工具:实现高效数据管理的核心技术
在当下数字化办公的环境中,局域网网络监控工具已成为保障企业网络安全、确保其高效运行的核心手段。此类工具通过对网络数据的收集、分析与管理,赋予企业实时洞察网络活动的能力。而在其运行机制背后,数据结构与算法发挥着关键作用。本文聚焦于 PHP 语言中的哈希表算法,深入探究其在局域网网络监控工具中的应用方式及所具备的优势。
30 7
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
28 4
单位电脑监控软件中 PHP 哈希表算法的深度剖析与理论探究
数字化办公的时代背景下,单位电脑监控软件已成为企业维护信息安全、提升工作效率的关键工具。此类软件可全面监测员工的电脑操作行为,收集海量数据,故而高效管理和处理这些数据显得尤为重要。数据结构与算法在此过程中发挥着核心作用。本文将聚焦于哈希表这一在单位电脑监控软件中广泛应用的数据结构,并通过 PHP 语言实现相关功能,为优化单位电脑监控软件提供技术支持。
28 3
|
14天前
|
论内网电脑监控软件中 PHP 哈希表算法的深度剖析与探究
当代企业网络管理体系中,内网电脑监控软件占据着关键地位。其功能涵盖对员工电脑操作行为的实时监测,以此维护企业信息安全,同时助力企业优化网络资源配置,提升整体工作效能。在构建内网电脑监控软件的诸多技术中,数据结构与算法构成了核心支撑体系。本文聚焦于哈希表这一重要数据结构,深入剖析其在 PHP 语言环境下,如何为内网电脑监控软件的高效运作提供助力,并通过详实的代码示例予以阐释。
31 3
|
22天前
|
基于 Python 哈希表算法的员工上网管理策略研究
于当下数字化办公环境而言,员工上网管理已成为企业运营管理的关键环节。企业有必要对员工的网络访问行为予以监控,以此确保信息安全并提升工作效率。在处理员工上网管理相关数据时,适宜的数据结构与算法起着举足轻重的作用。本文将深入探究哈希表这一数据结构在员工上网管理场景中的应用,并借助 Python 代码示例展开详尽阐述。
38 3
探秘文件共享服务之哈希表助力 Python 算法实现
在数字化时代,文件共享服务不可或缺。哈希表(散列表)通过键值对存储数据,利用哈希函数将键映射到特定位置,极大提升文件上传、下载和搜索效率。例如,在大型文件共享平台中,文件名等信息作为键,物理地址作为值存入哈希表,用户检索时快速定位文件,减少遍历时间。此外,哈希表还用于文件一致性校验,确保传输文件未被篡改。以Python代码示例展示基于哈希表的文件索引实现,模拟文件共享服务的文件索引构建与检索功能。哈希表及其分布式变体如一致性哈希算法,保障文件均匀分布和负载均衡,持续优化文件共享服务性能。
企业监控软件中 Go 语言哈希表算法的应用研究与分析
在数字化时代,企业监控软件对企业的稳定运营至关重要。哈希表(散列表)作为高效的数据结构,广泛应用于企业监控中,如设备状态管理、数据分类和缓存机制。Go 语言中的 map 实现了哈希表,能快速处理海量监控数据,确保实时准确反映设备状态,提升系统性能,助力企业实现智能化管理。
45 3

热门文章

最新文章