算法工具箱之哈希表

哈希表简介:

(1)哈希表是一个存储数据的容器,

(2)哈希表的作用:'快速'查找某个元素

(3)哈希表使用的范围:当频繁想查找某个元素时,这个时候就可以用哈希表

(4)哈希表使用的方法:1.任何一门高级语言都有哈希表这一个容器2.用数组模拟一个简易哈希表

下面通过几个实例来给大家分析哈希表如何运用在算法中:

两数之和

题目

思路

我们不从当前数字出发去寻找它的另一半,而是反过来思考:我需要什么样的数字才能凑成目标?遍历数组时,我们一边走一边记录见过的数字,每遇到一个新数字,就快速查看它的"另一半"(target - 当前数)是否在之前的记录中出现过。如果出现过,立即返回这对组合的下标;如果没出现过,就把当前数字存入记录,继续向前探索。这样,原本需要双重循环O(n²)的搜索问题,就变成了只需一次遍历O(n)的"查字典"游戏。

解法

复制代码
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        unordered_map<int,int> hash;
        for(int i = 0;i < nums.size();i++)
        {
            int x = target - nums[i];
            if(hash.count(x))
            {
                return {hash[x],i};
            }
            hash[nums[i]] = i;
        }
        return {0,0};
    }
};

判断是否互为字符重排

题目

思路

我们可以把字符串 s1看作仓库初始库存,在哈希表中记录每个字符的"存货数量"。然后,遍历第二个字符串 s2时,每个字符就像是从仓库取货,对应字符的库存减一。最后检查仓库是否被恰好清空------如果所有字符的库存都归零,说明两个字符串的字符组成完全一致,只是排列顺序不同;如果有些字符库存有余或不足,则说明它们无法通过重排互相转换。

解法

复制代码
class Solution {
public:
    bool CheckPermutation(string s1, string s2) 
    {
        vector<int> arr1(26,0);
        int size1 = s1.size();
        int size2 = s2.size();
        if(size1 != size2)
        {
            return false;
        }
        for(int i = 0;i < size1;i++)
        {
            char ch = s1[i];
            int x = ch - 97;
            arr1[x]++;
        }
        for(int j = 0;j < size2;j++)
        {
            char ch = s2[j];
            int x = ch - 97;
            arr1[x]--;
            if(arr1[x] < 0)
            {
                return false;
            }
        }
        return true;
    }
};

存在重复元素I

题目

思路

我们可以利用哈希表,仅需存储数「组内的元素」。在遍历数组的时候,⼀边检查哈希表中是否 已经出现过当前元素,⼀边将元素加⼊到哈希表中。如果某个数字重复出现,那么就返回true,如果遍历完整个数组没有重复出现,那么就返回false。

解法

复制代码
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        unordered_set<int> hash;
        for(int i = 0;i < nums.size();i++)
        {
            if(hash.count(nums[i]))
            {
                return true;
            }
            hash.insert(nums[i]);
        }
        return false;
    }
};

存在重复元素II

题目

思路

遍历数组时将当前元素和下标存入哈希表,若遇到重复元素,则比较当前下标与哈希表中记录的下标差值是否满足条件。如果满足条件则立即返回结果;否则,用当前下标覆盖 哈希表中旧的下标------因为下标递增,旧下标不可能与未来相同元素匹配得更近。这样既保证了查找的实时性,又通过不断"淘汰"过时的下标,确保了匹配的总是最近的相同元素,从而高效判断是否存在满足条件的索引对。

解法

复制代码
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) 
    {
        unordered_map<int,int> hash;
        for(int i = 0;i < nums.size();i++)
        {
            if(hash.count(nums[i]))
            {
                if(i - hash[nums[i]] <= k)
                {
                    return true;
                }
                else
                {
                    hash[nums[i]] = i;
                }
            }
            hash[nums[i]] = i;
        }
        return false;
    }
};
相关推荐
tod11316 小时前
C++ 核心知识点全解析(六)
c++·算法·面试经验
m0_5312371716 小时前
C语言-编程实例
c语言·开发语言·数据结构
紫陌涵光16 小时前
701. 二叉搜索树中的插入操作
算法·leetcode
tankeven16 小时前
HJ100 等差数列
c++·算法
ADDDDDD_Trouvaille16 小时前
2026.2.22——OJ98-100题
c++·算法
闻缺陷则喜何志丹16 小时前
【差分数组】P9166 [省选联考 2023] 火车站|普及+
数据结构·c++·洛谷·差分数组
tankeven16 小时前
HJ99 自守数
c++·算法
一只理智恩16 小时前
基于 CesiumJS + React + Go 实现三维无人机编队实时巡航可视化系统
前端·人工智能·算法·golang·无人机
菜鸡儿齐16 小时前
leetcode-分割回文串
算法·leetcode·职场和发展
重生之我是Java开发战士16 小时前
【优选算法】链表:两数相加,两两交换节点,重排链表,合并K个升序链表,K个一组反转链表
数据结构·算法·链表