【算法系列】哈希表

目录

哈希表总结

leetcode题目

一、两数之和

二、判定是否互为字符重排

三、存在重复元素

四、存在重复元素 II

五、字母异位词分组

六、在长度2N的数组中找出重复N次的元素

七、两个数组的交集

八、两个数组的交集 II

九、两句话中的不常见单词


哈希表总结

1.存储数据的容器

2.需要快速查找数据时,用哈希表

3.当题目中给定的字符串或者数组只包含小写字母或数据范围是0~100/1000等等时,可以用数组模拟哈希表

4.当数据范围是负数到正数时,不建议用数组模拟哈希表,因为还要加一个数转化之后进行映射,建议直接使用STL容器

leetcode题目

一、两数之和

1. 两数之和 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/two-sum/1.题目解析

给定数组与target, 返回和为target的两个元素下标

2.算法分析

解法一: 暴力枚举

策略一: 先固定一个数,然后依次与该数之后的数相加

策略二: 先固定一个数,然后依次与该数之前的数相加

解法二: 使用哈希表优化

暴力解法之所以慢,以策略二为例,  是因为枚举到nums[i]时,要在这个位置之前都遍历一下,看哪个数字等于target-nums[i], 所以如果我们枚举到nums[i]时,前面的数字都被扔进了哈希表中,我们就可以以O(1)的时间复杂度找到结果~

注意:如果是用哈希表暴力枚举策略一,最好是倒着遍历~

3.算法代

暴力枚举策略一:

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

暴力枚举策略二:

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

哈希表优化策略一:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        unordered_map<int, int> hash; //<nums[i], i>
        for(int i = nums.size()-1; i >= 0; i--)
        {
            int x = target - nums[i];
            if(hash.count(x)) 
                return {hash[x], i};
            hash[nums[i]] = i;
        }
        return {-1, -1}; //照顾编译器
    } 
};

哈希表优化策略二:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) 
    {
        unordered_map<int, int> hash; //<nums[i], i>
        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 {-1, -1}; //照顾编译器
    } 
};

二、判定是否互为字符重排

面试题 01.02. 判定是否互为字符重排 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/check-permutation-lcci/1.题目解析

给定两个字符串,判断一个字符串是否能够通过重排变成另一个字符串

2.算法分析

如果s1能够重排形成s2,  那么s1每个字符出现的个数和s2对应字符出现的个数是相等的!于是可以使用哈希表,而题目中说字符串只有小写字母,因此用数组模拟哈希表即可。所以解法就是用两个哈希表,然后判断哈希表是否相等即可;

优化1: 只使用一个哈希表统计s1中字符个数,然后遍历第二个字符串,把对应字符在哈希表中的个数--, 如果--之后是负数了,返回false即可

优化2: 两个字符串的长度不相等,直接返回false即可

3.算法代码

class Solution {
public:
    bool CheckPermutation(string s1, string s2)
    {
        //优化
        if(s1.size() != s2.size()) 
            return false;
            
        int hash[26] = {0};
        for(auto& e : s1)   
            hash[e - 'a']++;
        for(auto& e : s2)
        {
            hash[e - 'a']--;
            if(hash[e - 'a'] < 0)
                return false;
        }
        return true;
    }
};

三、存在重复元素

217. 存在重复元素 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/contains-duplicate/1.题目解析

数组中存在重复元素返回true, 不存在重复元素返回false

2.算法分析

使用哈希表解决问题~

3.算法代码

unordered_map:

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        unordered_map<int, int> hash;
        for(auto& e : nums)
        {
            hash[e]++;
            if(hash[e] > 1) 
                return true;
        }
        return false;
    }
};

unordered_set: 

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        unordered_set<int> hash;
        for(auto& e : nums)
        {
            if(hash.count(e)) 
                return true;
            else
                hash.insert(e);
        }
        return false;
    }
};

四、存在重复元素 II

219. 存在重复元素 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/contains-duplicate-ii/1.题目解析

判断数组中是否存在两个相同的元素,并且下标的绝对值小于等于k

2.算法分析

从前向后遍历数组,同时将遍历过的元素和下标绑定扔进哈希表,遍历的同时判断是否满足题意即可

小细节:nums = [1 0 2 1 3 1 4],  k =2,   当遍历到第2个1时,发现下标i-j=3>k, 不满足题意,此时将1和下标3绑定扔进哈希表覆盖之前的 <1, 0> 是完全可以的, 因为题目求的是 i-j <= k, 因此i和j越近越好,因此我们可以直接覆盖原先的值~

3.算法代码

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) 
    {
        unordered_map<int, int> hash; // <nums[i], i>
        for(int i = 0; i < nums.size(); i++)
        {
            if(hash.count(nums[i]) && i-hash[nums[i]] <= k)
                return true;
            hash[nums[i]] = i;
        }
        return false;
    }
};

五、字母异位词分组

49. 字母异位词分组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/group-anagrams/description/1.题目解析

给一个字符串数组,将所有的字母异位词放到一组,返回一个二维数组

2.算法分析

1.判断两个字符串是否是字母异位词(可以用哈希表,但是代码不好写,我们选择直接排序, 排序结果一样,那就互为字母异位词)

2.将相同的字母异位词分组 --- 借助哈希表 <string, string[ ]>, 哈希表第一个位置存储排序后的字符串,第二个存储一个字符串数组;

3.算法代码

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) 
    {
        unordered_map<string, vector<string>> hash;
        //1.将所有的字母异位词分组
        for(auto& s : strs)
        {
            string tmp = s;
            sort(tmp.begin(), tmp.end());
            hash[tmp].push_back(s);
        }
        //2.提取结果
        vector<vector<string>> ret;
        for(auto& [x, y] : hash)
        {
            ret.push_back(y);
        }
        return ret;
    }
};

六、在长度2N的数组中找出重复N次的元素

961. 在长度 2N 的数组中找出重复 N 次的元素 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/description/1.题目解析

我们在深剖一下题意,本质就是只有1个数重复出现了,其他数都只出现了一次

2.算法分析

思路一: 遍历数组,将当前元素和出现次数丢进哈希表,当某个数出现次数 == n时,返回该数

思路二: 遍历数组,进循环先判断该数是否已经存在,存在就直接返回,不存在就将该数丢进哈希表

3.算法代码

思路一:

class Solution {  
public:  
    int repeatedNTimes(vector<int>& nums)  
    {  
        size_t n = nums.size() / 2;
        unordered_map<int, int> hash; // [x, count]  
        for(auto& e : nums)  
        {  
            hash[e]++;  
            if(hash[e] == n)   
                return e;  
        }  
        return -1;
    }  
};

思路二:

class Solution {  
public:  
    int repeatedNTimes(vector<int>& nums)  
    {  
        unordered_map<int, int> hash; // [x, count]  
        for(auto& e : nums)  
        {  
            if(hash[e] == 1) // 只需要检查是否已经存在(即重复了一次)  
                return e;  
            hash[e]++;  
        }  
        return -1;
    }  
};

七、两个数组的交集

349. 两个数组的交集 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/intersection-of-two-arrays/submissions/

1.题目解析

返回两个数组的交集(输出结果的每个元素要是唯一的)

2.算法分析

将两个数组元素扔进两个 unordered_set 哈希表进行去重,然后遍历其中一个哈希表,看该哈希表中的元素在另一个哈希表中是否存在,存在就插入到结果数组中!

3.算法代码

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) 
    {
        vector<int> ret;
        unordered_set<int> hash1;
        unordered_set<int> hash2;
        for(auto& e : nums1) //对nums1元素去重
            hash1.insert(e);
        for(auto& e : nums2) //对nums2元素去重
            hash2.insert(e);

        for(auto& e : hash1)
            if(hash2.count(e))
                ret.push_back(e);
        return ret;
    }
};

八、两个数组的交集 II

350. 两个数组的交集 II - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/intersection-of-two-arrays-ii/1.题目解析

返回两个数组的交集 (结果中可以有重复元素)

2.算法分析

定义一个哈希表 unordered_map,遍历第一个数组,将 数组元素和出现的个数绑定扔进哈希表, 然后遍历第二个数组,元素在哈希表中出现,就插入到结果数组中,然后将该元素在哈希表中的个数--即可

3.算法代码

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) 
    {
        unordered_map<int, int> hash;
        for(auto& e : nums1)
            hash[e]++;

        vector<int> ret;
        for(auto& e : nums2)
        {
            if(hash[e])
            {
                ret.push_back(e);
                hash[e]--;
            }
        }
        return ret;
    }
};

九、两句话中的不常见单词

884. 两句话中的不常见单词 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/uncommon-words-from-two-sentences/description/

1.题目解析

返回两句话中互相在另一句话中没有出现的所有单词

2.算法分析

可以将两个字符串合在一起,提取出所有的单词同时扔进哈希表统计单词出现的次数,然后遍历一遍哈希表,出现次数为1的单词就是我们要的结果

3.算法代码

class Solution {
public:
    vector<string> uncommonFromSentences(string s1, string s2) 
    {
        //1.将所有的单词提取出来
        vector<string> words;
        string tmp;
        string s = s1 + ' ' + s2;
        unordered_map<string, int> hash;
        for(size_t i = 0; i <= s.size(); i++)
        {
            if(s[i] != ' ' && i != s.size())
                tmp += s[i];
            else
            {
                words.push_back(tmp);
                hash[tmp]++;
                tmp.clear();
            }
        }

        //2.从哈希表中提取结果
        vector<string> ret;
        for(auto [x, y] : hash)
            if(y == 1)
                ret.push_back(x);
        return ret;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/587219.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HC-SR04超声波测距

什么是超声波 超声波是频率高于20000赫兹的声波。 超声波是一种特定频率范围内的声波&#xff0c;其特点在于频率高于人耳能够感知的上限&#xff0c;即超过20千赫兹&#xff08;Hz&#xff09;。这种高频率的声波具有一些独特的性质&#xff1a; 方向性好&#xff1a;超声波…

托普利兹矩阵(T矩阵)及其应用(Matlab demo测试)

托普利兹矩阵&#xff08;T矩阵&#xff09;及其应用&#xff08;Matlab demo测试&#xff09; 1. 概念2. Matlab简单测试2.1 生成测试2.2 基本性质及原理2.3 性质验证 3. 其他应用总结3.1 其他性质3.2 文献阅读看到的 参考资料 1. 概念 托普利兹矩阵&#xff0c;简称为T型矩阵…

可视化大屏在真实场景的效果,绝对震撼,不要再嘲笑其作用了

hello&#xff0c;我是大千UI工场&#xff0c;本地带来一批可视化大屏现场效果图&#xff0c;非常震撼&#xff0c;给大家带来身临其境的感受&#xff0c;欢迎关注点赞&#xff0c;有需求请私信。 有人可能会认为可视化大屏没有太多价值&#xff0c;可能是因为以下几个原因&am…

npm 安装 pnpm 时 报错 npm ERR! Unexpected token ‘.‘

问题 一个项目用的是 pnpm 安装的依赖&#xff0c;node 的版本是 16.16.0&#xff0c;nvm 的版本是 1.1.7&#xff0c;然后全局安装 pnpm 报错如下&#xff1a; 解决 我看网上的一些解决方案是说 nvm 版本过低导致&#xff0c;下面我们按照这个方向处理。 实首先下载 nvm-up…

Linux 文件管理命令Lawk wc comm join fmt

文章目录 2.Linux 文件管理命令2.44 awk&#xff1a;模式匹配语言1&#xff0e;变量2&#xff0e;运算符3&#xff0e;awk 的正则4&#xff0e;字符串函数5&#xff0e;数学函数案例练习 2.45 wc&#xff1a;输出文件中的行数、单词数、字节数案例练习2.46 comm&#xff1a;比较…

康姿百德学生床垫价格合理,为孩子提供健康睡眠环境

康姿百德集团公司学生床垫&#xff0c;关爱孩子的睡眠和健康 每个孩子都是家长新中的宝贝&#xff0c;在孩子健康成长的道路上&#xff0c;良好的睡眠起着至关重要的作用。而选择一款优质的床垫&#xff0c;不仅能帮助孩子更快进入梦乡&#xff0c;还能促进他们的健康发育。在…

最好的数据恢复应用程序:哪个是您首选的最佳文件恢复软件?

如今&#xff0c;智能设备无处不在&#xff0c;导致我们中的许多人无可辩驳地被大量数据所包围。随着大量数据的涌入得到一致的处理&#xff0c;无意中删除重要文档或不同文件&#xff0c;存在丢失这些数据的迫在眉睫的危险。 最好的数据恢复应用程序 对于每一个最好的数据恢复…

Python 与 TensorFlow2 生成式 AI(三)

原文&#xff1a;zh.annas-archive.org/md5/d06d282ea0d9c23c57f0ce31225acf76 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第七章&#xff1a;使用 GAN 进行风格转移 神经网络在涉及分析和语言技能的各种任务中正在取得进步。创造力是人类一直占有优势的领域&…

Stm32CubeMX 为 stm32mp135d 添加网卡 eth

Stm32CubeMX 为 stm32mp135d 添加网卡 eth 一、启用设备1. eth 设备添加2. eth 引脚配置2. eth 时钟配置 二、 生成代码1. optee 配置2. uboot 配置3. linux 配置 bringup 可参考&#xff1a;Stm32CubeMX 生成设备树 一、启用设备 1. eth 设备添加 我这里只启用一个eth设备&…

uniapp 桌面应用插件 Ba-Launcher

简介&#xff08;下载地址&#xff09; Ba-Launcher 可以让你的应用成为简单的桌面应用&#xff0c;如需扩展功能&#xff0c;请联系我。 截图展示 可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 使用方法也很简单&#xff0c;在插…

GPT3 终极指南(一)

原文&#xff1a;zh.annas-archive.org/md5/6de8906c86a2711a5a84c839bec7e073 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 GPT-3&#xff0c;或者说是 Generative Pre-trained Transformer 3&#xff0c;是由 OpenAI 开发的基于 Transformer 的大型语言模型…

LLama3最新医疗大模型安装与应用指南

为什么要介绍医疗模型&#xff0c;因为平时我们工作繁忙&#xff0c;可能身体不舒服也会&#xff0c;拖着到不得已的时候才到医院&#xff0c;特别是老年人怕麻烦&#xff0c;拖延更严重。如果有了这些模型&#xff0c;我们可以向这些模型提问&#xff0c;给一个初步的了解&…

openlayer 使用ol-ext插件实现凸显区域

使用ol-ext插件实现凸显多变形 效果如图 1、创建openlayer var map; var view; var tileLayer, source, vector;function init() {tileLayer new ol.layer.Tile({source: new ol.source.TileArcGISRest({url: "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStr…

算法:双指针题目练习

目录 题目一&#xff1a;移动零 题目二&#xff1a;复写零 题目三&#xff1a;快乐数 题目四&#xff1a;盛最多水的容器 题目五&#xff1a;有效三角形的个数 题目六&#xff1a;和为s的两个数字(剑指offer) 题目七&#xff1a;三数之和 题目八&#xff1a;四数之和 常…

有关CSS中排版常见问题(清除默认样式问题 + 元素居中问题 + 元素之间的空白问题 + 行内块的幽灵空白问题)

前言&#xff1a;在练习CSS排版的时候&#xff0c;我们经常会遇到一些排版上的问题&#xff0c;那么我们如何去解决这些问题呢&#xff1f;本篇文章给出了一些新手在练习排版时候可能会遇到的问题的解决方案。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我…

【Windows,亲测有效】手动激活Sublime Text

前言 Sublime Text 是一款非常好用的文本编辑器&#xff0c;但是免费版时不时会跳弹窗 本方法无毒无害&#xff0c;简单易上手 2023/12/22 更新&#xff1a;实测从 4143 支持到 4169 开始 先确保你用的是官方版本的 Sublime Text&#xff0c;还没下的可以去官方下载&#…

题目 2671: 推导部分和

题目描述: 对于一个长度为 N 的整数数列 A1, A2, AN&#xff0c;小蓝想知道下标 l 到 r 的部分和 是多少&#xff1f; 然而&#xff0c;小蓝并不知道数列中每个数的值是多少&#xff0c;他只知道它的 M 个部分和的值。其中第 i 个部分和是下标 li 到 ri 的部分和 &#xf…

类加载子系统之类的生命周期(待完善)

0、前言 文中大量图片来源于 B站 黑马程序员 0.1、类加载子系统在 JVM 中的位置 类加载器负责的事情是&#xff1a;加载、链接、解析 0.2、与类的生命周期相关的虚拟机参数 参数描述-XX:TraceClassLoading打印出加载且初始化的类 1、类的生命周期 堆上的变量在分配空间的时…

LiveCD镜像文件的定制化

最近想要定制化一款属于自己的LiveCD镜像文件&#xff0c;并且里边封装好所需要的软件程序&#xff0c;本文将会记录具体的操作步骤&#xff0c;供有需要的人参考借鉴。 环境说明&#xff1a; 环境配置说明配置参数编码环境Centos7.9LiveCD文件CentOS-7-livecd-x86_64.iso 附…

基础安全:CSRF攻击原理与防范

CSRF的概念 CSRF(Cross-Site Request Forgery)中文名为“跨站请求伪造”。这是一种常见的网络攻击手段,攻击者通过构造恶意请求,诱骗已登录的合法用户在不知情的情况下执行非本意的操作。这种攻击方式利用了Web应用程序中用户身份验证的漏洞,即浏览器在用户完成登录后会自…