【算法】哈希表专题

一. (1.) 两数之和

算法原理:

1.暴力解法:从前往后

用两遍for循环,固定一个数,在这个数之前遍历看是否相加等于目标值,正反遍历都可以,但哈希表优化是基于反向遍历的

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

2.哈希表优化

直接将固定数前面的数都放入哈希表中,查找哈希表中是否存在值为target-固定数的元素,有就直接返回两数下标,没有就将固定数放入哈希表中。这样的好处不用每一个数都要遍历一次数组查找,直接查找一次哈希表即可,时间复杂度从n方降为n,空间复杂度为n,哈希表是以空间换时间的策略

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

二. (⾯试题 01.02.) 判定是否互为字符重排

算法思路:

  1. 当两个字符串的⻓度不相等的时候,是不可能构成互相重排的,直接返回 false
  2. 如果两个字符串能够构成互相重排,那么每个字符串中各个字符出现的次数⼀定是相同的。因此,我们可以分别统计出这两个字符串中各个字符出现的次数,然后逐个⽐较是否相等即可。这样的话就可以选择哈希表来统计字符串中字符出现的次数。
  3. 该题字符都是小写字母,可用数组模拟哈希表(适合数据量小且集中),降低空间复杂度
cpp 复制代码
class Solution {
public:
    bool CheckPermutation(string s1, string s2) {
        if(s1.size()!=s2.size()) return false;
        int hash[26]={0};
        for(auto s:s1) hash[s-'a']++;
        for(auto s:s2) hash[s-'a']--;
        for(int i=0;i<26;i++) if(hash[i]!=0) return false;
        return true;
    }
};

三. (217.) 存在重复元素

算法原理:

题目至少出现两次的意思就是数组中存在重复元素,不需要计算元素出现次数只需查找当前元素在之前是否出现过即可,与两数之和思想一样。

可以使用哈希表,存储元素出现次数即可,一遍检查哈希表是否出现过当前元素,一边将(之前没出现过的)当前元素加入哈希表中

cpp 复制代码
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        unordered_set<int>hash;
        for(auto num:nums)
        {
            if(hash.count(num)) return true;
            hash.insert(num);
        }
        return false;
    }
};

四. (219.) 存在重复元素 II

算法原理:

与两数之和思想一样,利用哈希表,将元素值和下标绑定存入其中,在找当前元素之前是否重复出现元素同时判断其下标相减是否符合要求。

注意当出现重复元素放入哈希表中会产生覆盖,这里允许覆盖因为题目要求下标差值为<=,由于是从左往右遍历,先入哈希表的重复数据被覆盖不会有影响因为先入的能符合题意,后重复的元素一定符合题意,反之就不行。

cpp 复制代码
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])&&(i-hash[nums[i]]<=k)) return true;
            else hash[nums[i]]=i;
        }
        return false;
    }
};

五. (49.) 字⺟异位词分组

算法原理:

互为字⺟异位词的单词有⼀个特点:将它们「排序」之后,两个单词应该是完全相同的。

所以,我们可以利⽤这个特性,将单词按照字典序排序,如果排序后的单词相同的话,就划分到同⼀组中。这时我们就要处理两个问题:

• 排序后的单词与原单词需要能互相映射;

• 将排序后相同的单词,划分到同⼀组;

可以利用哈希表特性,key为排序后的字符串,value为string数组来存储所有异位词,这样就能处理每一个字符串不会重复添加,因为排序后的字符串都作为key值当索引,去找到对应的异位词数组添加原始字符串即可

cpp 复制代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,vector<string>>hash;
        //1.将字符串分组放入哈希表
        for(auto str:strs)
        {
            string tmp=str;
            sort(tmp.begin(),tmp.end());
            hash[tmp].push_back(str);
        }
        //2.将哈希表中value值取出当返回结果
        vector<vector<string>>ret;
        for(auto [x,y]:hash)
        {
            ret.push_back(y);
        }
        return ret;
    }
};
相关推荐
乐迪信息9 小时前
乐迪信息:智慧煤矿视觉检测平台:从皮带、人员到矿车
大数据·人工智能·算法·安全·视觉检测·推荐算法
蒹葭玉树9 小时前
【C++上岸】C++常见面试题目--数据结构篇(第十六期)
数据结构·c++·面试
睡不醒的kun9 小时前
leetcode算法刷题的第二十三天
数据结构·c++·算法·leetcode·职场和发展·贪心算法
mit6.8249 小时前
[re_2] rpc|http|nginx|protobuf|
网络·c++
初级炼丹师(爱说实话版)9 小时前
8.30美团技术岗算法第二题
python·算法
要做朋鱼燕9 小时前
【C++】 Vector容器操作全解析
开发语言·c++·笔记·学习笔记
CoovallyAIHub9 小时前
突破闭集限制:3D-MOOD 实现开集单目 3D 检测新 SOTA
深度学习·算法·计算机视觉
利刃大大10 小时前
【高并发内存池】三、线程缓存的设计
开发语言·c++·缓存·项目·内存池
Miracle&10 小时前
C++后端开发重点知识点
开发语言·c++