代码随想录day8-哈希表(2)

代码随想录-day8 哈希表(2)

1、LeetCode 438 找到字符串中的所有异位词

题目分析:
本题的暴力思路就是对p进行排序,然后对s中的每一个字串进行排序,理论上可以求出结果,但是不断的排序导致时间复杂度非常高,直接超出时间限制,所以是不可行的。
本题可以使用哈希表加滑动窗的思路进行:
首先根据p出现的字数建立哈希表,然后s也根据p的长度同时建立次数哈希表,一旦两个哈希表相等,就代表异位词出现了。不管出现还是没出现,s字符串中长位lenP的窗都要移动一位。
由于字母的数量是有限的,所以我们使用数组来实现哈希表。

题目解答:

class Solution {
public:vector<int> findAnagrams(string s, string p) {// 本题实际上可以使用滑动窗口结合哈希表的思路来解决// 由于字母的数量是有限的,所以可以用数组来实现哈希表int lenS = s.size();int lenP = p.size();if (lenS < lenP) return {};vector<int> ans;vector<int> countS(26, 0);vector<int> countP(26, 0);for (int i = 0; i < lenP; i++) {countP[p[i] - 'a']++;  // 统计p中每个字母出现的次数countS[s[i] - 'a']++;  // 统计s中前lenP个字母出现的次数}if (countP == countS) ans.emplace_back(0);  // 如果正好相等了,那么第一个异位词的起始就是0// 滑动窗口for (int i = 0; i < lenS - lenP; i++) {countS[s[i] - 'a']--;  // 开始进来是0,前面已经判断过了,肯定不是,所以清除这,后面就相当于一个一个向后移动countS[s[i + lenP] - 'a']++;  // 前面移动,后面也要移动if (countS == countP) ans.emplace_back(i + 1);  // i+1才是入口}return ans;}
};

2、LeetCode 349 两个数组的交集

题目分析:
求两个数组的交集,而且不考虑重复的元素,本题就是一个典型的使用set的哈希表的题目。
两个特点:

  • 不重复
  • 一个元素在不在另一个集合里面

所以考虑使用set来进行操作,而unordered_set底层使用哈希表实现,查询速度最快。

题目解答:

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> set1(nums1.begin(), nums1.end());  // 使用初始化的方法定义set1unordered_set<int> res;    for (auto num : nums2) {if (set1.find(num) != set1.end()) {  // 如果查询到了,就加到结果中res.emplace(num);}}return vector<int>(res.begin(), res.end());  // 注意这种返回的方式}
};

实际上,这个题目给定了数组的长度[1,1000]以及数组中每个数的大小限制,我们可以直接用数组来实现哈希表。一个关键的过程就是,一旦出现了,我就认为你出现的次数是1,这样也就达到了去重的目的。

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {// 由于这个题目给定了nums的长度以及num的大小上限,可以使用数组来实现哈希表vector<int> hash(1001, 0);vector<int> ans;for (auto& num : nums1) {hash[num] = 1;  // 只要你出现过,次数就是一次,这里的作用和set本质上就是一样的了}for (auto& num : nums2) {if (hash[num] == 1) {  // 在nums1中出现过的数字在nums2中也出现了ans.emplace_back(num);hash[num]--;  // 为了避免nums2中还有相同的,这里直接让hash[num]--,避免重复}}return ans;}
};

3、LeetCode 350 两个数组的交集 II

题目分析:
这个题还是求交集,跟之前的那道题目不同的是,这个题要求如果存在重复的元素,也要输出出来,那么这道题就不能使用set来做,因为重复是考虑在我们的里面的。
首先使用map来统计nums1中的每个数字出现的次数,然后遍历nums2数组,如果发现其中的值也在nums1中,就将其加到结果中,否则跳过即可,注意匹配过的数字,在nums1中也要相应减1。

题目解答:

class Solution {
public:vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {// 使哈希表统计nums1中各个元素出现的次数unordered_map<int, int> umap;vector<int> ans;// umap[num]需要初始化吗,有一说一,c++默认操作,如果见不存在,则会创建一个新的键,值是0for (int num : nums1) umap[num]++;  // 统计出现的次数for (int num : nums2) {if (umap[num] != 0) {  // 一旦在nums1中出现的元素在nums2中出现了,就将其存在结果中umap[num]--;ans.emplace_back(num);}}return ans;}
};

这里有一个需要注意的地方,就是map的值的初始化问题,自增统计次数到底有没有意义。
chatgpt的回答:对于每个 num,umap[num]++ 操作会首先访问 umap 中对应的键 num,如果 num 不存在,则会创建一个键值对 num:0。因为这个键值对刚刚被创建,所以它的值为 0,接着自增操作将其值变为 1。
注意这里是会自己创建的,所以下面的代码是合理的:

    unordered_map<int, int> umap;cout << umap[100] << endl;

在这里插入图片描述
注意:这个题目也给了数组的长度以及数组中数据的最大值,所以我们也可以用数组来实现哈希表,但是会造成大量的空间浪费

4、LeetCode 202 快乐数

题目分析:
这个题目乍一看是一个数学题,类似于水仙花那种数学题,但是不然。这个题目中有一个非常关键的一句话,如果不是快乐·数,则会陷入无限循环。循环是什么意思,就是能回到原点啊,那么能回到原点的一定就不是快乐数,反之,不能回到原点的总有一次会能满足和为1,即快乐数。
思路理清之后,我们就很明确这道题可以直接用set啊,一旦回来了,就一定不是快乐数。
另外,这个题目还有一个地方也是需要学习的,就是如何巧妙的得到数字的各个位,针对这个问题,我之前做了一个很蠢的事情,那就是题目给出了这个数字的最大值是2^31-1,那就好了,我直接就弄那么多个数,然后得到每一位,具体的做法如下:

    vector<int> getPosition(int n) {// 由于最大的数是2^31 - 1, 也就是2,147,483,647,一共有10位vector<int> res(10, 0);vector<int> num = { (int)1e9, (int)1e8, (int)1e7, (int)1e6, (int)1e5, (int)1e4, (int)1e3, (int)1e2, 10, 1 };int sum = 0;for (int i = 0; i < 10; i++) {for (int j = i - 1; j >= 0; j--) {sum += res[j] * num[j];}res[i] = (n - sum) / num[i];sum = 0;}return res;}

大概的意思就是说,比如我要获取1234,我直接用1234/1000 = 1,这就是第一位,然后第二位就是(1234-11000)/100=2,第三位:(1234-11000-2*100)/10=3,第四位就是4,总之来说非常
其实一般而言,我们获取数字的每一位,并不是从前往后,而是从后往前不断获取。可以使用递归或者循环来实现。

void getPosition(int num) {// 使用递归来实现int s = 0;if (num > 0) {s = num % 10;cout << s << " ";getPosition(num / 10);}
}
void getPosition(int num){// 使用循环来实现int s = 0;while (num) {s = num % 10;cout << s << " ";num /= 10;	}
}

然后接下来就是很简单的操作了。

class Solution {
public:bool isHappy(int n) {unordered_set<int> uset;uset.emplace(n);  // 如果不是快乐数的话,也迟早循环到这个数int sum = getSum(n);while (1) {if (sum == 1) return true;  // 如果和为1,直接返回if (uset.find(sum) != uset.end()) return false;  // 如果找到了,说明这个就不是快乐数else {uset.emplace(sum);sum = getSum(sum);}}return false;}// 得到和int getSum(int& n) {int sum = 0;while (n) {int temp = n % 10;sum += temp * temp;n /= 10;}return sum;}
};

5、LeetCode 1 两数之和

题目分析:
这个题的暴力思路其实非常简单,一个一个遍历,然后从下一个元素开始遍历,一旦二者的和是target,直接返回即可。但是这样的暴力算法的时间复杂度为O(n),十分耗时。
我们前面提到的可以用set以及数组来实现哈希表,但是这个题就是典型的使用ma的题目,因为它不仅要求我们存储值,还要求返回坐标呢。
具体的思路就是,依次遍历数组中的元素,如果target-num不在哈希表中,那么就添加进去,键为num的值,值为num的位置,因为我们map的查找是查找的键。
题目解答:

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> umap;vector<int>  ans;for (int i = 0; i < nums.size(); i++) {auto it = umap.find(target - nums[i]);if (it == umap.end()) umap[nums[i]] = i;  // ==end()就代表找不到else return {umap[target - nums[i]], i};  // 如果找到了,那就把target-num[i]的坐标和当前的i返回}return {};}
};

6、LeetCode 454 四数相加Ⅱ

题目分析:
本题的难度不大,分析如下:

  • 首先是本题的数组是分开的,那就不考虑到重复的问题,跟后面的三数之和以及四数之和是不一样的;
  • 本题只要求返回有多少个元组,并没有要求你返回这些元组。
    本题的思路如下,四个数组两两一组,定义一个哈希表,哈希表的键为两个数组的和的组合出现的次数,然后寻找另外两个数组的和的键是不是在哈希表中出现过,出现过几次最终的答案就是几次。
class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {// 使用哈希表来做,弄清楚本题的实质unordered_map<int, int> umap;  // 键是a+b,值是a+b出现的次数int ans = 0;  // 结果for (auto& a : nums1) {for (auto& b : nums2) {umap[a + b]++;  // 这句话就可以统计出键a+b的值的次数了}}for (auto& c : nums3) {for (auto& d : nums4) {if (umap.find(- c - d) != umap.end()) {  // 说明c+d在umap中出现过ans += umap[- c - d];  // 一旦出现了,就能跟umap中的进行组合。这里是加的-c-d出现的次数}}}return ans;}
};

注意: 这里ans每次加的是umap[-c-d],也就是每出现一次,就可以和之前的所有情况进行组合。两次写代码都写成了ans++;非常严重的错误。
如果这个题不仅要求返回个数,同时要求返回元组呢?

vector<vector<int>> fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, vector<vector<int>>> umap;  // 键是a+b,值是a+b出现的次数int len = nums1.size();vector<vector<int>> ans;for (int i = 0; i < len; i++) {for (int j = 0; j < len; j++) {umap[nums1[i] + nums2[j]].push_back({i, j});  // 这句话就可以统计出键a+b的值的次数了}}for (int i = 0; i < len; i++) {for (int j = 0; j < len; j++) {auto it = umap.find(-nums3[i] - nums4[j]);if (it != umap.end()) {  // 说明c+d在umap中出现过vector<vector<int>> temp = it->second;int count = temp.size();  // umap中相反数出现的次数,对应不同的组合for (int k = 0; k < count; k++) {temp[k].push_back(i);  // 对每一个和出现的情况的vector末尾追加i和jtemp[k].push_back(j);ans.push_back(temp[k]);}}}}return ans;
}int main() {vector<int> nums1 = {-1,-1}, nums2 = {-1,1}, nums3 = {-1,1}, nums4 = {1,-1};vector<vector<int>> res = fourSumCount(nums1, nums2, nums3, nums4);for (int i = 0; i < res.size(); i++) {for (int j = 0; j < res[0].size(); j++) {cout << res[i][j] << " ";}cout << endl;}return 0;
}

结果如图所示:
在这里插入图片描述
今天接触哈希表的第二天,对哈希表的认识更近了一步。当涉及查找一个元素是不是在集合里面的时候,考虑使用哈希表。如果要求不重复,优先使用set,如果可以确定数组的大小,可以使用数组实现哈希表,如果牵涉到要存映射数据,比如第6题,就考虑使用map来解决。
要在这个世界上获得成功,就必须坚持到底:至死都不能放手。——伏尔泰

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

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

相关文章

ChatGPT上线了!请使用java语言写一个bert模型结构?

ChatGPT上线了!请使用java语言写一个bert模型结构?有没有感觉自己要失业了? 好的,以下是使用 Java 语言实现 BERT 模型结构的代码示例。 复制 import java.io.IOException; import java.util.List; import java.util

外资公司章程标准范本

外资公司章程标准范本 第一章 总则 第一条根据《中华人民共和国外资企业法》及其实施细则&#xff0c;&#xff08;公司、先生或女士&#xff09;&#xff08;以下简称投资者&#xff09;在______投资设立外商独资企业“_______有限公司”&#xff08;以下简称公司&#xff09;…

法国在华企业名单,坚决抵制!

法国商品商标&#xff1a; 法国的汽车&#xff1a;雪铁龙 雷诺 标致。 超市&#xff1a;家乐福 欧尚。 法国洋酒&#xff1a;人头马、轩尼诗XO、马爹利。 酒庄&#xff1a;木桐 拉菲 拉图庄园 玛歌 玛 歌Margaux 欧 颂Ausone 大依瑟索Grands Echezeaux 依瑟索Echezeaux …

巴西的《全面隐私法》现已生效

在经历了立法上的不确定性之后&#xff0c;巴西现已正式颁布了该国第一部通用数据保护法&#xff0c;即“ Le Geral deProteode Dados”或“ LGPD”。尽管行政制裁要到2021年8月1日才生效&#xff0c;但个人和检察官现在可以提出损失索赔。实际上&#xff0c;至少已经提起了一项…

《加州消费者隐私法案》解读合集,CCPA手册发布,助力企业出海合规

2021年&#xff0c;越来越多的中国企业开始展现出强大的国际竞争力&#xff0c;鼓舞着万千中国互联网企业进军海外。另一方面&#xff0c;随着各国开始制定各自的隐私保护、数据安全、数据合规法律&#xff0c;出海企业也面临着运营合规的难题。 数美科技致力于为企业线上业务…

欧盟加密监管法案通过,美国急了?

万众期待的欧盟《加密资产市场监管法案》&#xff08;Markets in Crypto-Assets Regulation&#xff0c;简称MiCA&#xff09;终于在5月16日尘埃落定。 尽管在4月20日&#xff0c;该方案已在欧洲议会全体会议上投票通过&#xff0c;但直到5月16日&#xff0c;包括27个国家的欧盟…

欧盟授权代表EU Representative是什么?

欧盟授权代表(European Authorised Representative 或European Authorized Representative)是指由位于欧洲经济区EEA(包括EU与EFTA)境外的制造商明确指定的一个自然人或法人。该自然人或法人可代表EEA境外的制造商履行欧盟相关的指令和法律对该制造商所要求的特定的职责。 职…

6-爬取英语外教和中国老师招聘数据,并将其进行对比(薪资、学历、经验等)...

说明&#xff1a; 项目主要爬取英语外教与中国老师招聘数据&#xff0c;并对数据进行比较分析。 外教的招聘信息&#xff08;JobLeadChina网站&#xff09;&#xff1a;http://www.jobleadchina.com/job?job_industryTeaching 中国老师的招聘信息&#xff08;万行教师人才网站…

建议所有教英语的教师,狠狠的用这好东西‼️

新教师上英语课沉闷无聊&#xff0c;学生提不起学习兴趣&#xff1f;可以在课件中下功夫&#xff0c;各种外语配音应有尽有&#xff0c;让你的英语课堂生动有趣&#xff0c;学生从心里爱上英语&#xff01; 另外各位老师们有时候上公开课 不满足于课本的音频 想要新建一个录音…

英语老师自用省心天花板小程序

英语老师复工几天了&#xff01;今天来分享款英语老师都爱的天花板级别小程序&#xff0c;亲测实用&#xff0c;自用省 心&#xff01;&#xff01; 【101教育PPT】 老师教学都要提前备课&#xff0c;相对其他学科&#xff0c;英语老师找资料要较难一些&#xff0c;这款小程序里…

程序员怎么使用chatgpt提升工作效率?

对于程序员来说&#xff0c;大家想必都习惯了通过 ChatGPT 来生成代码&#xff0c;然后自己手动稍加调整&#xff0c;这样能在极短的时间内得到可以运行的代码。除了这种最常规的操作之外&#xff0c;本文想分享一些笔者在日常工作中是如何使用 ChatGPT 等 AI 工具提高自己工作…

chatgpt赋能python:Python为什么运行不出来?

Python为什么运行不出来&#xff1f; Python是一门高级编程语言&#xff0c;被广泛应用于科学计算、机器学习、Web开发等领域。但是&#xff0c;有时候我们在编写Python程序的过程中会遇到各种各样的问题&#xff0c;其中之一就是程序无法运行。那么&#xff0c;Python为什么会…

基于ChatGPT实现电影推荐小程序!

ChatGPT是 “美国AI梦工厂”OpenAI 开发的人工智能聊天机器人&#xff0c;让撰写邮件、论文、脚本&#xff0c;制定商业提案&#xff0c;创作诗歌、故事&#xff0c;甚至敲代码、检查程序错误都变得易如反掌。很多网友都感叹“只有你想不到&#xff0c;没有它做不到“。 OpenA…

chatGPT人工智能对话H5小程序openai写作论文毕业论文付费问答3.5接口源码分销好友fenx

ChatGPT最强人工智能对话模型 ChatGPT为你服务: 1. 知乎百度答题、做作业题目 2. 写代码、写文案、写论文&#xff0c;写小说 3. 文案润色、翻译、写诗作词 4. 扮演面试官、扮演书籍电影角色 5. 陪聊倾诉、解忧、讲故事&#xff0e; 6. 项目判断&#xff0c;资源寻找&am…

如何利用 ChatGPT 去快速了解一个行业?附案例实操

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 如何最近开始研究 AI 在各个行业下的应用。 都知道行研三部曲&#xff1a;第一步&#xff0c;首先不要开黄腔&#xff1b;第二步…

ChatGPT神奇用法:定点周边景点推荐,Get私人导游!

正文共 607字&#xff0c;阅读大约需要 3 分钟 周末游爱好人群必备技巧&#xff0c;您将在3分钟后获得以下超能力&#xff1a; 1.个人定制化旅行 2.轻松完成私人攻略 Beezy评级&#xff1a;B级 *经过简单的寻找&#xff0c; 大部分人能立刻掌握。主要节省时间。 推荐人 |Adam 编…

ChatGPT实现旅行安排

工作之余&#xff0c;出门旅行一趟放松放松身心&#xff0c;是对自己辛勤工作最好的犒劳方式之一。旅行可以近郊游、可以远游&#xff0c;可以穷游&#xff0c;可以自驾游&#xff0c;可以一言不合打飞的喂鸽子&#xff0c;方式多种多样。但是多数情况&#xff0c;我们是到一个…

充满可能的新一代辅助编程神器:Cursor

随着技术的不断进步&#xff0c;人工智能已经逐渐成为了编程领域中不可或缺的一部分。而今天我们要为大家介绍的&#xff0c;就是一款基于 GPT4 智能引擎&#xff0c;由 OpenAI 开发出来的全新辅助编程神器 — Cursor。 1、Cursor 编辑器 Cursor 作为一款智能代码编辑器&#x…

讯飞星火大模型体验报告

近日&#xff0c;科大讯飞召开了星火认知大模型成果发布会&#xff0c;会上表示讯飞星火大模型将突破开放式问答&#xff0c;对标ChatGPT&#xff0c;在中文能力上超过ChatGPT&#xff0c;在英文能力上与ChatGPT相当。对此&#xff0c;你怎么看&#xff1f; 笔者准备给bing/ch…

使用GPT-3训练一个垃圾短信分类器

平时我们都会收到很多短信&#xff0c;由于微信等即时通讯工具的普及&#xff0c;短信已经成为了一个验证码接收器&#xff0c;但是偶尔也有不少垃圾短信&#xff0c;所以对短信进行分类和屏蔽是一个很简单又很重要的需求。 目前在AppStroe上有很多实现短信分类的App&#xff…