当前位置: 首页 > news >正文

C++算法学习专题:哈希算法

                本篇内容我们就来学习一下算法界的一个经典算法思想:哈希算法

目录

什么是哈希表和哈希算法?

哈希算法有什么用?

什么时候用哈希算法?

怎么用哈希算法?

1、两数之和

2、判断是否为字符重排 

3、出现重复元素

4、出现重复元素2

5、字母异位词分组 


什么是哈希表和哈希算法?

        哈希表就是一个存储数据的容器。

        哈希算法(Hash Algorithm)是一种将任意长度的数据映射为固定长度值的单向加密函数。它通过特定的数学运算,将输入(也称为"消息")转换为一个固定长度的字符串(通常为十六进制表示),这个字符串称为哈希值或摘要。

        哈希算法具有以下核心特性:

  • 确定性:相同的输入总是产生相同的输出
  • 快速计算:对于给定数据,可以快速计算出哈希值
  • 不可逆性:从哈希值无法反推出原始数据
  • 抗碰撞性:很难找到两个不同的输入产生相同的哈希值
  • 雪崩效应:输入数据的微小变化会导致输出哈希值的巨大差异

哈希算法有什么用?

        “快速”查找某个元素(时间复杂度O(1))

什么时候用哈希算法?

        当我们需要频繁地查找某一个数据的时候可以用哈希算法。

        同时二分算法也可以,不过受限于排序

        但是哈希算法对于空间的损耗特别大。

怎么用哈希算法?

        任何高级语言都有哈希表这个容器(C语言没有)

        1、容器(哈希表)

        2、用数组模拟简易的哈希表。

哈希相关的资料可以参考文档:

<unordered_map> - C++参考

<unordered_set> - C++参考

1、两数之和

解法一:暴力枚举 

        1、先固定一个数字

        2、依次与该数之前的数相加

解法二:用哈希算法优化

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {//老版本写法:暴力解法// int left=0,right=nums.size()-1;// vector<int>arr=nums;// sort(arr.begin(),arr.end());// while(left<right)// {//     int sum=arr[left]+arr[right];//     if(sum==target)  //     {//         break;//     }//     else if(sum<target)  //     {//         ++left; //     }//     else if(sum>target)//     {//        --right; //     }  // }// int x = arr[left], y = arr[right];// left = right = -1;// for (int k = 0; k < nums.size(); ++k) // {//     if (nums[k] == x &&  left== -1)//         left = k;//     if (nums[k] == y)//         right = k;//     }// return { left, right };//新版本写法:哈希表、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};else{hash[nums[i]]=i;}}return {-1,-1};//返回无效下标}
};

2、判断是否为字符重排 

 解法思路:

        1、建立两个哈希表,分别用于统计字符出现的个数

优化:使用一个哈希表,统计s1,遍历s2的时候相同字符均减去1,若为0则相等,反之不等

        2、用数组模拟哈希表。

        时间复杂度O(n)

class Solution {
public:bool CheckPermutation(string s1, string s2) {if(s1.size()!=s2.size()){return false;}int hash[26]={0};//统计s1的信息for(auto ch:s1){//利用'a'映射的下标为0hash[ch-'a']++;}//扫描第二个字符串for(auto ch:s2){hash[ch-'a']--;if(hash[ch-'a']<0){return false;}}return true;}
};

3、出现重复元素

         答案:

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

4、出现重复元素2

        答案:

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;}hash[nums[i]]=i;}    return false;}
};

5、字母异位词分组 

解题思路:

1、排序

2、分组:

答案: 

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

        本期的内容先到这里,作者后续还会进一步地深入学习哈希表及其哈希算法

        喜欢请点个赞谢谢

http://www.dtcms.com/a/304550.html

相关文章:

  • 预装Windows 11系统的新电脑怎么跳过联网验机
  • AI峰-关于AI的意识-AI浪潮下
  • 【高等数学】第七章 微分方程——第三节 齐次方程
  • 代码随想录——数组——移除元素——双指针
  • openeuler24.03部署k8s1.32.7高可用集群(三主三从)
  • 《Spring Cloud Config配置中心核心原理与动态刷新方案》
  • Singapore
  • 聚观早报 | 三星获特斯拉AI芯片订单;小米16首发成安卓最强SOC;iPhone 17 Pro支持8倍光学变焦
  • Kubernetes 核心准备:从 Pod 本质到网络模型全解析
  • 作物生长模型Oryza V3实战16:气象数据集
  • 个人健康管理小程序(消息订阅、Echarts图形化分析)
  • 如何调整服务器的内核参数?-哈尔滨云前沿
  • 随着人工智能技术的飞速发展,大语言模型(Large Language Models, LLMs)已经成为当前AI领域最引人注目的技术突破。
  • Apache Ignite Cluster Groups的介绍
  • 多目标粒子群优化(MOPSO)解决ZDT1问题
  • 嵌入式系统分层开发:架构模式与工程实践(一)
  • Spring Boot 2整合MyBatis Plus详细指南
  • 【面试场景题】阿里云子账号设计
  • 从零开始学习Dify-爬取网站文章,批量提取和输出热点摘要(十)
  • CRMEB电商系统集群部署指南:阿里云COS静态文件加速与资源分离最佳实践
  • 聊聊测试环境不稳定如何应对
  • 人工智能与法律:智能司法的创新与挑战
  • C++ 进阶
  • Typecho handsome新增评论区QQ,抖音,b站等表情包
  • 【Clumsy】只是学习记录
  • 晶界能计算
  • flexiblejs + pxtorem 实现浏览器缩放适配:兼顾系统缩放与文本放大体验
  • 图形界面应用程序技术栈大全
  • getgff.py脚本-python006
  • 【学习路线】游戏开发大师之路:从编程基础到独立游戏制作