leetcode-哈希表

1. 理论

从哈希表的概念、哈希碰撞、哈希表的三种实现方式进行学习

在这里插入图片描述

哈希表:用来快速判断一个元素是否出现集合里。也就是查值就能快速判断,O(1)复杂度;

哈希碰撞:拉链法,线性探测法等。只是一种思想,刷题我们自己是无需实现的,只是使用;

哈希表的三种实现方式:数组,set(集合),map(映射)。其中集合和映射分别又有三种实现。

2. 做题的时候用到的小tip:

  1. set和vector不能直接相互转换,但可以通过遍历一个容器并将其元素插入另一个容器实现数据转换。

以下是将 std::set 转换为 std::vector 和将 std::vector 转换为 std::set 的示例:

std::set 转换为 std::vectorstd::vector<int> myVector(mySet.begin(), mySet.end());

std::vector 转换为 std::setstd::set<int> mySet(myVector.begin(), myVector.end());

如果不是定义,直接return的时候,就用return set<int>(myVector.begin(), myVector.end()); 就行。

3. 有效的字母异位词

本题用数组就能完成,但是用到的是哈希思想。

class Solution {
public:bool isAnagram(string s, string t) {if(s.length()!=t.length())return false;int hash[26] = {0};for(char i : s){hash[i-'a']++;}for(char i : t){hash[i-'a']--;}for(int i : hash){if(i != 0)  return false; }return true;}
};

4. 两个数组的交集Leetcode349. 20230904 set操作、转换、哈希思想

如果使用unordered_set(底层为哈希表),代码如下:

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int>result_nums;// 最终返回的交集unordered_set<int>tmp_nums(nums1.begin(), nums1.end());// 用于比较的集合        for(int i : nums2){if(tmp_nums.find(i) != tmp_nums.end()){result_nums.insert(i);}}return vector<int>(result_nums.begin(),result_nums.end()); }
};

写这一题的时候由于不熟悉set和vector之间的相互转换,卡了好久。思路倒是不难,但是要声明两个unordered_set。先是用第一个uset存nums1的所有值,然后比较nums2是否在uset里,如果在,就加入到第二个uset中去。

所以为什么要用一个uset存,而不是直接用nums2与vector的nums1比呢?这就是本题的哈希所在,因为对于unordered_set查找只需O(1时间,如果直接将nums2nums1vector比较,那么每次查找操作的平均时间复杂度将是O(n),因为在vector中查找元素需要遍历整个vector,而不是像unordered_set一样具有O(1)的查找时间。这会导致整个算法的时间复杂度更高。

这种做法的主要优势在于查找的时间复杂度更低,使得整个算法的性能更好。

如果使用数组,也是类似的:

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> result;int tmp[1000]={0};for (int i : nums1){tmp[i] = 1;}for (int j : nums2){if(tmp[j] == 1)result.insert(j);}return vector<int>(result.begin(),result.end());}
};

先用tmp 01数组存nums1中出现过的值,然后遍历nums2看tmp数组对应有没有变过,变过则插入uset。

然后我又做了一个不去重的交集题,麻烦的是有个限制条件让我们次数不一致取最小值,就要使用find之后erase iterator而不能直接用erase。这个也是我上网查了之后才知道的。

class Solution {

public:

    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {

        // 不去重,考虑使用multiset

        multiset<int> result;

        multiset<int> tmp(nums1.begin(),nums1.end());

        for(int i : nums2){

            auto it = tmp.find(i);

            if(it != tmp.end()){

                result.insert(i);

                tmp.erase(it);

            }

        }

        return vector<int>(result.begin(),result.end());

    }

};

这个我没检查就提交一次过了,晕晕

5. 快乐数 LeetCode. 202 20230905

这一题居然不是数学是哈希 还真是没想到。并且,这一题对于各位数取平方再相加的操作是我要学习的,当时写的时候觉得很头大,没想到包装成一个函数之后还是很容易的。

class Solution {
public:int calculatesum(int n){int sum = 0;while (n){sum += (n % 10) * (n % 10);n /= 10;}return sum;}bool isHappy(int n) {// 计算平方,填入哈希表并比较unordered_set<int> myset;int sum = n;while(sum != 1){sum = calculatesum(sum);if(myset.find(sum) != myset.end()){return false;}   else{myset.insert(sum);} }return true;}
};

6.两数之和 LeetCode 1. 20230905

老生常谈的题,但是每次做都有不一样的感受。前年只会暴力解,去年仅知道可以用unordered_map,今年的进步在于读懂了题目为什么这样出,限制不重复就是为了我们用unorder_map,限制时间复杂度其实就是提示unordered的查询和插入效率均为O(1)。

还有一个就是

iter->second     ,不带括号  

和return {a,b}; 这个用法不能忘掉。开始写的小括号,又换成中括号。

还有pair操作,是insert((pair)<int,int>(a,b))

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> mymap;int size = nums.size();for(int i = 0; i < size; ++i){auto it =  mymap.find(target - nums[i]);if( it != mymap.end()){return {i, it->second};}else{mymap.insert(pair<int,int>(nums[i],i));}}return {-1,-1};}
};

思想是遍历vector,用unordered_map存放之前遍历过的元素集合和它们对应的序号,每遍历到一个元素,在遍历过的集合里找是否有target减它的元素。

7.四数相加 II LeetCode 454. 20230908

思想是两个数组一起。前两个数组用于填充,后两个数组用于查询,跟之前一样。

需要注意的是可以可以直接使用umap[i]++这种操作。

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int,int> umap;int count = 0;for(int i : nums1){for(int j : nums2){umap[i+j]++;}}for(int i : nums3){for(int j : nums4){auto it = umap.find(-i-j);if(it != umap.end()){count += it->second;}}}return count;}
};

如果本题想难度升级:就是给出一个数组(而不是四个数组),在这里找出四个元素相加等于0,答案中不可以包含重复的四元组。

8.赎金信 LeetCode383. 20230908

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {int character[26]={0};for(char i : magazine){character[i-'a']++;}for(char i : ransomNote){character[i-'a']--;if(character[i-'a'] < 0)return 0;}return 1;}
};

现在看到简单题基本就是嘎嘎乱杀了,这一题完全无难度,三分钟秒掉。

有一点需要注意:数组需要初始化……TAT

9. 三数之和

这一题的数据就是一个数组,我还以为跟之前一样,是三个数组。

这一题不建议用哈希法,因为是“去重”的,建议的方法是排序+双指针+去重。

去重是三个地方,我写的代码还跟随想录不一样,先以自己的为主。

遇到了一个坑:i++和continue,应该写continue,因为-4,-2,-2,-2,0,1,2,2,2,3,3,4,4,6,6

这个里面,i如果到了第二个-2,会直接+1,然后到了第三个-2又能够顺利往下运行,然后又会找到和第二个-2相同的三元组。想了好久的。

正确的做法应该是第二个-2:跳过!

第三个-2:跳过!

这样就能到0。

贴一个我自己写出来的代码:

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(),nums.end());for(int i = 0; i < nums.size(); ++i){if(nums[i] > 0)return result;if(i > 0 && nums[i] == nums[i - 1]){continue;}for(int left = i + 1, right = nums.size() - 1; left < right; ){if(nums[left] + nums[right] + nums[i] > 0){right--; }else if(nums[left] + nums[right] + nums[i] < 0){left++;}else {result.push_back({nums[i], nums[left], nums[right]}); //找到了一个答案left++;right--;while(left < right && nums[left] == nums[left - 1]) left++;//去重while(left < right && nums[right] == nums[right + 1]) right--;//去重}}}return result;}
};

10.四数之和

在这里插入图片描述

第一次提交通过了239/293个用例。但是,就这一行写了两个bug

①一开始写的不是j>1,复制了i>0过来,写的是if(i>0&&nums[j]==nums[j-1]),通过239/293

在这里插入图片描述
在这里插入图片描述

②后来写成图上的if(j>1&&nums[j]==nums[j-1])完全没考虑i==j的情况,于是改成if(j>i+1&&nums[j]==nums[j-1]),结果通过284/293……服了,然后改成longlong,结果因为中间结果是用int存的,还是不行

在这里插入图片描述

③然后把代码改成了这个丑陋的样子,终于过了,用时一个小时,啥也不想说了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

进程(详解)

进程 进程PCB进程的定义进程的组成进程模式进程的状态进程的运行进程的创建进程的结束孤儿进程僵尸进程僵尸进程的危害 进程的创建pidforkwait案例 进程 PCB 从操作系统理解进程概念-------先描述&#xff0c;后组织 为了使参与并发执行的程序能独立的运行&#xff0c;必须为之…

H5游戏源码分享-接苹果游戏拼手速

H5游戏源码分享-接苹果游戏拼手速 看看在20秒内能接多少个苹果 <html> <head><title>我是你的小苹果</title><meta charset"utf-8"/><meta name"viewport" content"initial-scale1, user-scalableno, minimum-scale…

【ARM 嵌入式 C 入门及渐进 10 -- 冒泡排序 选择排序 插入排序 快速排序 归并排序 堆排序 比较介绍】

文章目录 排序算法小结排序算法C实现 排序算法小结 C语言中常用的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。下面我们来一一介绍&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a;冒泡排序是通过比较相邻元素的大小进行排…

本机spark 通idea连接Oracle的坑

1. 报错&#xff1a;Exception in thread "main" java.lang.NoSuchMethodError: scala.Product.$init$(Lscala/Product;)V 查询网上资料&#xff0c;是idea引入的scala运行环境版本与idea默认的scala版本不一样 也就是写的项目中的pom的spark版本与idea默认的版本不…

【设计模式】第4节:创建型模式之“单例模式”

一、介绍 采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法。 不使用单例模式的UML类图&#xff1a; 使用单例模式的UML类图&#xff1a; 使用场景&#xff1a; 需要频繁创建或销毁的对象…

H5游戏分享-烟花效果

<!DOCTYPE html> <html dir"ltr" lang"zh-CN"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width" /> <title>点击夜空欣赏烟花</title> <sc…

Zabbix监控oxidized备份状态

Zabbix监控oxidized备份状态 原理是利用oxidized的hooks功能调用zabbix_sender推送数据给zabbix_server 参考 https://cloud.tencent.com/developer/article/1657025 https://github.com/clontarfx/zabbix-template-oxidized https://github.com/ytti/oxidized/blob/master/…

Python 日期和时间处理教程:datetime 模块的使用

Python 中的日期不是独立的数据类型&#xff0c;但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象。 示例&#xff1a;导入 datetime 模块并显示当前日期&#xff1a; import datetimex datetime.datetime.now() print(x)日期输出 当我们执行上面示例中的代码…

如何确保PCIe Gen3通道的信号质量

PCIe 3.0设计面对的挑战 PCIe由PCI-SIG协会研发和维护的一个高速标准接口&#xff0c;PCIe3.0是其开发的第三代接口高速差分接口&#xff0c;其单个差分对信号速率可到达8.0Gbps&#xff0c;目前其以广泛的应用于计算机服务器等设备领域。 下图显示的是一个典型的PCIe Gen3的…

天气数据可视化平台-计算机毕业设计vue

天气变幻无常&#xff0c;影响着我们生活的方方面面&#xff0c;应用天气预报信息可以及时了解天气的趋势&#xff0c;给人们的工作、生活等带来便利&#xff0c;也可以为我们为未来的事情做安排和打算&#xff0c;所以一个精准的、易读 通过利用 程序对气象网站大量的气象信息…

ArcGIS笔记13_利用ArcGIS制作岸线与水深地形数据?建立水动力模型之前的数据收集与处理?

本文目录 前言Step 1 岸线数据Step 2 水深地形数据Step 3 其他数据及资料 前言 在利用MIKE建立水动力模型&#xff08;详见【MIKE水动力笔记】系列&#xff09;之前&#xff0c;需要收集、处理和制作诸多数据和资料&#xff0c;主要有岸线数据、水深地形数据、开边界潮位驱动数…

【C++】STL容器——探究不同 [ 迭代器 ] 种类&在STL中的使用方式(15)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 引言&#xff1a;一.查看STL使用文档时…

Java-API简析_java.io.FilterOutputStream类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/134106510 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

【蓝桥每日一题]-前缀和与差分(保姆级教程 篇3)#涂国旗 #重新排序

目录 题目&#xff1a;涂国旗 思路&#xff1a; 题目&#xff1a;重新排序 思路&#xff1a; 题目&#xff1a;涂国旗 思路&#xff1a; 乍一看好像没啥思路&#xff0c;但是我们需要涂最少的格子&#xff0c;所以要都尝试一下才行&#xff0c;也就是从上面开始白至少一行&am…

selenium测试框架快速搭建(ui自动化测试)

一、介绍 selenium目前主流的web自动化测试框架&#xff1b;支持多种编程语言Java、pythan、go、js等&#xff1b;selenium 提供一系列的api 供我们使用&#xff0c;因此在web测试时我们要点页面中的某一个按钮&#xff0c;那么我们只需要获取页面&#xff0c;然后根据id或者n…

【DevChat】智能编程助手 - 使用评测

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

如何监听/抓取两个设备/芯片之间“UART串口”通信数据--监视TXD和RXD

案例背景&#xff1a;全网仅此一篇&#xff01;&#xff01;&#xff01; 两个设备/芯片之间采用UART串口通信。我们如何实现芯片1 TXD – > 芯片2 RXD&#xff0c;芯片2 TXD --> 芯片1 RXD两个单线链路上的数据抓取和监听&#xff1f;这篇博客将告诉您。 目录 1 什么是…

Mybatis延迟加载(缓存)

延迟加载 分步查询的优点&#xff1a;可以实现延迟加载&#xff0c;但是必须在核心配置文件中设置全局配置信息&#xff1a;lazyLoadingEnabled&#xff1a;延迟加载的全局开关。当开启时&#xff0c;所有关联对象都会延迟加载 aggressiveLazyLoading&#xff1a;当开启时&…

VSCode编写Unity代码自动补全配置

1.下载并安装.NET 7.0&#xff08;C#插件需要&#xff09;和.NET Framework 4.7.1&#xff08;Unity需要&#xff09; .NET 7.0下载链接&#xff1a;https://dotnet.microsoft.com/en-us/download .NET Framework 4.7.1下载链接&#xff1a;https://dotnet.microsoft.com/en-…

灯光布置和场景模拟软件:Set A Light 3D Studio

Set A Light 3D Studio是一款专业的灯光模拟软件&#xff0c;旨在帮助摄影师和电影制片人在电脑上进行虚拟灯光布置和场景模拟&#xff0c;以实现更加精准和高质量的拍摄效果。该软件提供了丰富的灯光和场景模型&#xff0c;支持灵活调整光源位置、强度、颜色和效果等参数&…