算法02哈希法

算法01之哈希法

  • 1.哈希法理论基础
    • 1.1哈希表
      • (1)哈希表
      • (2)哈希函数
      • (3)哈希碰撞
    • 1.2哈希法基本思想
    • 1.3哈希法适用场景与最常用的哈希结构
  • 2.LeetCode242:有效的字母异位词
    • (1)图解本题的哈希内核
    • (2)cpp代码
  • 3.LeetCode349:两个数组的交集
    • (1)图解本题哈希内核
    • (2)cpp代码
  • 4.LeetCode202:快乐数
  • 5.LeetCode1:1. 两数之和

1.哈希法理论基础

1.1哈希表

(1)哈希表

哈希表是一种数据结构,用于存储键值对(key-value pairs)。它通过将键(key)通过哈希函数映射到一个特定的索引位置来实现快速的数据访问。这个索引位置在内存中的数组或桶(buckets)中,使得在常数时间复杂度内可以进行查找、插入和删除操作。

想象一下你的家里有一个带有标签的抽屉。每个标签都对应着一个抽屉里的物品。当你需要某样东西时,你不必搜索整个房子,而是直接根据标签找到对应的抽屉,这就像哈希表根据键找到对应的数值一样。这种快速定位的方式使得你能够在瞬间找到你需要的物品,就像哈希表可以在常数时间内找到相应的值。

(2)哈希函数

哈希函数是一种将输入数据映射为固定长度散列值(哈希值)的函数。其主要目的是将任意长度的数据转换为固定长度的输出,通常是一个固定大小的数字或字节序列。

哈希函数具有以下特性:

  • 确定性: 相同的输入始终产生相同的哈希值。
  • 高效性: 计算速度快,能在合理时间内完成计算。
  • 离散性: 输入数据的微小变化应该导致输出哈希值的显著变化。
  • 不可逆性: 理论上不可通过哈希值逆向计算出原始输入数据。

常见的哈希函数有MD5、SHA-1、SHA-256等,它们被广泛用于数据加密、数据完整性验证、密码存储等领域。

想象你是一位魔术师,你有一个魔法箱子用来存放各种物品。你的目标是将每样物品放进箱子里,并在箱子的每个格子上放置一个标签。这个标签不仅告诉你物品存放在哪里,还得保证这个标签是独一无二的。你使用一个特殊的变化魔法(哈希函数),这个魔法会将每件物品都转化成一个独特的魔法标签,让你可以快速地找到它们。所以,当你需要取出某样物品时,你只需使用这个特殊魔法,它会让你知道这个物品的魔法标签,而这个标签对应着箱子的一个格子。这就好像哈希函数把数据变成一个特殊的“标签”,让你可以迅速找到存放的位置。而哈希函数的“魔法”在于,无论你放进去什么样的物品,它总是能给你一个独一无二的标签,就像每件物品都有一个特殊的魔法标签一样。

(3)哈希碰撞

在这里插入图片描述

哈希碰撞指的是不同的输入数据经过哈希函数计算后得到了相同的哈希值。在理想情况下,哈希函数应该能够将不同的输入映射到不同的哈希值,但在实际应用中,由于哈希函数将无限的输入空间映射到有限的输出空间,发生哈希碰撞是可能的。

想象一下你是一个魔术师,你的“蓝条”是有限的,当你的蓝条不足时,你的魔术可能会失灵而不准确。在你的魔法失效时,这就可能会发生原来是一个标签对应一个物品的情况而编程一个标签对应两个或两个以上的物品。“蓝条”就相当于是哈希表的存储空间,一个标签对应多个物品就是哈希碰撞

哈希冲突可以通过以下几种方法解决:

  • 开放寻址法(Open Addressing):这种方法在哈希冲突发生时,会寻找哈希表中的下一个可用位置,并尝试将数据存储在那里。这包括线性探测、二次探测、双重哈希等技术,逐个检查直到找到空槽来解决冲突。

在这里插入图片描述

  • 链表法(Chaining):哈希表中的每个槽位不只是一个单独的位置,而是一个链表或其他数据结构。当发生哈希冲突时,将新的键值对添加到该位置的链表中。这样,相同哈希值的元素都可以存储在同一个位置上,而不会发生覆盖。

在这里插入图片描述

  • 再哈希(Rehashing):当哈希表负载因子过高时,可以重新调整哈希表的大小,通常是增大容量,然后重新哈希所有的键值对到新的表中。这可以减少冲突的发生,因为新的更大的表提供了更多的空间来均匀分布键值对。

  • 完美哈希函数(Perfect Hashing):这是一种在特定情况下能够完全避免冲突的方法。完美哈希函数能够保证每个键都映射到不同的位置,但在实际中找到完美哈希函数可能比较困难。

选择哪种方法取决于应用的需求和数据特性。链表法在处理冲突时比较灵活,但需要更多的存储空间。开放寻址法则在空间效率上更高,但可能需要更多的探测步骤来解决冲突。再哈希和完美哈希函数则更多地关注于降低冲突的概率。

1.2哈希法基本思想

哈希法是一种基于哈希函数和哈希表的技术,用于将数据映射到一个固定范围的索引位置,以实现快速的查找、插入和删除操作。这个技术的核心是哈希函数,它将数据转换为哈希值,然后将该哈希值映射到哈希表中的特定位置。

1.3哈希法适用场景与最常用的哈希结构

在算法问题中,哈希法通常用于:

  • 快速查找: 哈希函数将数据映射为索引,使得在哈希表中能够以常数时间复杂度(O(1))进行查找操作。
  • 判断元素是否存在: 通过哈希表的结构,可以快速判断一个元素是否在集合中。
  • 去重操作: 将数据存储在哈希表中,可以自动去除重复元素,只保留唯一的元素。

2.LeetCode242:有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram” 输出: true

示例 2:

输入: s = “rat”, t = “car” 输出: false

提示:

1 <= s.length, t.length <= 5 * 104 s 和 t 仅包含小写字母

(1)图解本题的哈希内核

在这里插入图片描述

(2)cpp代码

//在s中出现的一个字母,我们就增加其在OrccrenceWord中的值
//在t中出现该字母,我们就减少其在orccrenceWord中的值
//如果s和t字符串是有效字母的异位词,OrccurenceWord的每一项最后应该都是0
//因为对一组异位词,s对一个字母提供的正增量刚好等于t对一个字母提供的负增量
class Solution {
public:
    bool isAnagram(string s, string t) {
        int OrccrenceWord[26] = {0};

        for(int i: s)
        {
            OrccrenceWord[i - 'a']++;
        }

        for(int i: t)
        {
            OrccrenceWord[i - 'a']--;
        }

        for(int i = 0; i < 26; i++)
        {
            if(OrccrenceWord[i] != 0)
            {
                return false;
            }
        }

        return true;

    }
};

3.LeetCode349:两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4] 输出:[9,4] 解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000 0 <= nums1[i], nums2[i] <=
1000

(1)图解本题哈希内核

在这里插入图片描述

(2)cpp代码

//unordered_set是一种常用的数据结构,适合在原数据规模很大或者原数据十分离散的情况
//unordered_set就像我们数学中的集合一样,满足两个主要特性:1.无需;2.不重复
//result存储结果
//nums1_set利用这个数据结构(类)的构造函数,哈希映射nums1,对齐进行去重
//遍历nums2,如果nums2中的元素在nums1中出现了,就把它插入到结果哈希表(result)中,最后返回结果哈希表
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    
    unordered_set<int> result;
    unordered_set<int> nums1_set(nums1.begin(), nums1.end());

    for(int n: nums2)
    {
        if(nums1_set.find(n) != nums1_set.end())
        {
            result.insert(n);
        }
    }
    return vector<int>(result.begin(), result.end()); 

    }
};

4.LeetCode202:快乐数

5.LeetCode1:1. 两数之和

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

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

相关文章

Linux:终端定时自动注销

这样防止了&#xff0c;当我们临时离开电脑这个空隙&#xff0c;被坏蛋给趁虚而入 定几十秒或者分钟&#xff0c;如果这个时间段没有输入东西那么就会自动退出 全局生效 这个系统中的所有用户生效 vim /etc/profile在末尾加入TMOUT10 TMOUT10 这个就是10 秒&#xff0c;按…

【QT】Model/View结构

目录 1 概述 2 Mode/View基本原理 3 数据模型 4 视图组件 5 代理 6 Model/View结构的一些概念 6.1 Model/View的基本结构 6.2 模型索引 6.3 行号和列号 6.4 父项 6.5 项的角色 1 概述 Model/View&#xff08;模型/视图&#xff09;结构是Qt中用界面组件显示与编辑数据的一种结构…

在scrapy 使用selenium模拟登录获取cookie

前言 最近有一点点爬虫需求&#xff0c;想总结一下scrapy框架的一些基本使用方法&#xff0c;加深印象&#xff0c;自己一直习惯使用一些脚本文件运行爬虫&#xff0c;面对数据量非常大&#xff0c;稳定性要求比较高的&#xff0c;效率需求比较高的情况下还是用scrapy较为合适…

vue-springboot二手家电家用电器商城交易管理系统java毕业设计

本二手家电管理平台是为了提高用户查阅信息的效率和管理人员管理信息的工作效率&#xff0c;可以快速存储大量数据&#xff0c;还有信息检索功能&#xff0c;这大大的满足了用户和管理员这两者的需求。操作简单易懂&#xff0c;合理分析各个模块的功能&#xff0c;尽可能优化界…

final的详解

在Java中&#xff0c;final 关键字用于表示不可改变的实体&#xff0c;可以应用于变量、方法、类和指令重排序。它有不同的作用&#xff0c;具体取决于它被应用的上下文。 1.对于变量&#xff1a; 如果一个变量被声明为 final&#xff0c;则该变量的值在一旦被赋予后就不能再被…

C++共享和保护——(5)编译预处理命令

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 耕耘者的汗水是哺育种子成长的乳汁&am…

制造企业可以通过哪些措施改善设备OEE

设备综合效率OEE&#xff08;Overall Equipment Effectiveness&#xff09;是制造企业衡量设备效率的关键指标之一。高效的设备运行对于提高生产效率、降低成本和实现竞争优势至关重要。然而&#xff0c;实现高水平的设备OEE并不是一项简单的任务。本文将介绍一些制造企业可以采…

基于博弈树的开源五子棋AI教程[1 位棋盘]

0 引子 常见的五子棋棋盘大小为15x15&#xff0c;最直观的表示就是一个二维数据。本文为了易于拓展一开始使用的是QVector<QVector>的数据&#xff0c;但是在分支因子为10的情况下只能搜索到4层左右&#xff0c;后面深度加深&#xff0c;搜索时间呈指数倍数增长。这种实…

【LeetCode刷题】--245.最短单词距离III

245.最短单词距离III class Solution {public int shortestWordDistance(String[] wordsDict, String word1, String word2) {int len wordsDict.length;int ans len;if(word1.equals(word2)){int prev -1;for(int i 0;i<len;i){String word wordsDict[i];if(word.equa…

算法基础之约数个数

约数个数 核心思想&#xff1a; 用哈希表存每个质因数的指数 然后套公式 #include <iostream>#include <algorithm>#include <unordered_map>#include <vector>using namespace std;const int N 110 , mod 1e9 7;typedef long long LL; //long l…

互式流程图|BPMN JointJS+ JavaScript 3.7.3 Crack

JointJS 是 JavaScript 图表库为卓越的 UI 提供支持 使用经过验证的库快速、自信地构建高级视觉和无代码/低代码应用程序。 赋能全球行业领导者 使用 JointJS 构建的图表 一个库&#xff0c;‍无限 UI 选项 直接在您的应用程序中享受交互式流程图、BPMN 和其他图表工作室。利用…

MyBatis的配置文件

目录 MyBatis配置 1.properties标签 2.typeAliases标签 3.Mappers标签 一个最全面的MyBatis配置文件可能会包含各种不同的设置和选项&#xff0c;根据实际情况&#xff0c;可以根据需要添加或删除配置。以下是一个包含各种可能设置的示例。 这个配置文件包含了环境设置、数…

详细解析POI 和 EasyExcel

在数据量需要被批量导入、导出的时候&#xff0c;就可以使用POI和easyExcel 常用场景&#xff1a; 1、将用户信息导出为excel表格(导出数据…) 2、将Excel表中的信息录入到网站数据库&#xff08;习题上传…&#xff09;大大减轻网站录入量!开发中经常会设计到excel的处理&am…

Unity中Shader平移变换

文章目录 前言方式一&#xff1a;对顶点本地空间下的坐标进行相加平移1、在属性面板定义一个四维变量记录在 xyz 上平移多少。2、在常量缓冲区进行申明3、在顶点着色器中&#xff0c;在进行其他坐标转化之前&#xff0c;对模型顶点本地空间下的坐标进行转化4、我们来看看效果 方…

卷积层里的多输入与多输出通道(channel)

目录 一、多输入输出通道 1、多输入通道 2、多输出通道 3、11卷积层 4、二维卷积层的计算复杂度 5、总结 二、代码实现 1、多输入通道 2、多输出通道 3、11卷积层 4、总结 一、多输入输出通道 1、多输入通道 下图是多输入通道、单输出通道的情况&#xff1a;每个通道…

.NET 药厂业务系统 CPU爆高分析

Windbg 分析 1. CPU 真的爆高吗 还是老规矩&#xff0c;要想找到这个答案&#xff0c;可以使用 !tp 命令。 0:044> !tp logStart: 1 logSize: 200 CPU utilization: 88 % Worker Thread: Total: 8 Running: 4 Idle: 4 MaxLimit: 1023 MinLimit: 4 Work Request in Queue: …

翻译: 负责任的人工智能 Responsible AI

负责任的人工智能指的是以道德、值得信赖和社会负责任的方式开发和使用人工智能。许多开发者、企业和政府都关心这一点&#xff0c;并且一直在进行对话&#xff0c;也在努力确保人工智能的构建和使用是负责任的。由于对负责任的人工智能的所有这些关注和努力&#xff0c;我们在…

网线制作,集线器、交换机、路由器的介绍以及路由器的设置

目录 一. 网线制作 1.1 制作材料 1.2 网线标准 1.3 网线做法 二. 集线器、交换机、路由器介绍 前言 简介 简单来说 三. 路由器的设置 设置1 设置2 设置3 设置4 无线设置 一. 网线制作 1.1 制作材料 网线 …

【进阶篇】YOLOv8实现K折交叉验证——解决数据集样本稀少和类别不平衡的难题,让你的模型评估更加稳健

YOLOv8专栏导航&#xff1a;点击此处跳转 K折交叉验证 K折交叉验证&#xff08;K-Fold Cross-Validation&#xff09;是一种常用的机器学习模型评估方法&#xff0c;可以帮助我们评估模型的性能&#xff0c;特别适用于数据集相对较小的情况。 在K折交叉验证中&#xff0c;将原…

CUMT--Java--JDBC编程

目录 一、JDBC简介 二、数据库访问 1、加载数据库驱动 2、建立数据连接 3、创建Statement对象 4、执行SQL语句 5、访问结果集 三、MetaData接口 1、DatabaseMetaData接口 2、ResultSetMetaData接口 四、事务 1、JDBC中的事务 2、保存点 3、批量更新 一、JDBC简…