算法工具箱之哈希表

哈希表简介:

(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;
    }
};
相关推荐
HaiLang_IT2 小时前
【信息安全毕业设计】基于双层滤波与分割点改进孤立森林的网络入侵检测算法研究
网络·算法·课程设计
hansang_IR2 小时前
【记录】AT_abc400模拟赛
c++·算法·模拟赛
iAkuya2 小时前
(leetcode)力扣100 59括号生成(回溯||按括号序列的长度递归)
算法·leetcode·职场和发展
共享家95272 小时前
双指针算法(一)
数据结构·算法·leetcode
十八岁讨厌编程2 小时前
【算法训练营 · 二刷总结篇】回溯算法、动态规划部分
算法·动态规划
近津薪荼2 小时前
优选算法——滑动窗口2(数组模拟哈希表)
c++·学习·算法
金枪不摆鳍2 小时前
算法基础-哈希表
算法·哈希算法
渐暖°2 小时前
【leetcode算法从入门到精通】9. 回文数
算法·leetcode·职场和发展
星火开发设计2 小时前
using 关键字:命名空间的使用与注意事项
开发语言·c++·学习·算法·编程·知识