C++刷题 -- 哈希表

C++刷题 – 哈希表

文章目录

  • C++刷题 -- 哈希表
    • 1.两数之和
    • 2.四数相加II
    • 3.三数之和(重点)


当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法;

1.两数之和

https://leetcode.cn/problems/two-sum/
一种方法是直接两个for循环暴力求解,时间复杂度为O(N^2);

另一种解法:使用map记录遍历过的元素

  • 每次遍历一个元素,计算其与target的差值,从map中寻找差值,若存在,则返回下标,若不存在,则将遍历完的元素插入map;
class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> nums_map; //记录遍历过的元素vector<int> res;for(int i = 0; i < nums.size(); i++){int diff = target - nums[i];if(nums_map.find(diff) != nums_map.end()) // 差值>0且已经遍历{res.push_back(i);res.push_back(nums_map[diff]);break;}else{// diff不在map中,将遍历过的元素插入mapnums_map.insert(make_pair(nums[i], i));}}return res;}
};

2.四数相加II

https://leetcode.cn/problems/4sum-ii/

  • 将四个数组分为两组,计算出所有nums1和nums2中每个元素的和,使用map保存结果和个数;
  • 然后再遍历nums3和nums4中的元素,计算0 - nums3[i] - nums4[j]的值,结果在map中寻找,如果找到,就在结果中增加相应的个数;
class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> sum_map;int count = 0;for(const auto& n1 : nums1) // 保存nums1和nums2中所有对应元素的和与个数{for(const auto& n2 : nums2){sum_map[n1 + n2]++;}}for(const auto& n3 : nums3) // 遍历nums3和nums4,差值在map中寻找{for(const auto& n4 : nums4){int diff = 0 - n3 - n4;if(sum_map.find(diff) != sum_map.end()){count += sum_map[diff];}}}return count;}
};

3.三数之和(重点)

https://leetcode.cn/problems/3sum/description/

  • 这道题不适合用哈希法,哈希法可以通过O(N^2)的for循环得到两个数的和,并存放在哈希表中,再通过差值寻找第三个数,但这样会造成重复下标,去重的过程很麻烦;
  • 可以使用双指针法
    请添加图片描述
  • 拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。
  • 依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i],b = nums[left],c = nums[right]。
  • 接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。
  • 如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。
    时间复杂度:O(n^2)。
  • 最重要的部分其实是去重
  • a的去重
    都是和 nums[i]进行比较,是比较它的前一个,还是比较它的后一个。
    如果仅比较后一个:
    在这里插入图片描述
    那我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1,那这组数据就pass了。
    不能有重复的三元组,但三元组内的元素是可以重复的!因此需要和前一个已经遍历过的数据对比;
    在这里插入图片描述
  • b与c的去重
    对b和c的去重如果放在找到三元组之前,就会漏掉0,0,0这种情况
    因此left和right的去重应放在找到三元组之后
    如果找到一个三元组后,left右边或者right左边是重复的,那么可以去掉,因为此时三元组有两个数已经确定了,这个三元组就是唯一的,因此重复的left或者right就需要去掉
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> res;sort(nums.begin(), nums.end()); // 先排序数组//begin从左向右遍历//left和right在begin的右边,计算三者的和,如果小于0,left++,如果大于0,right--//直到找到目标数字或者left和right越界或者相遇for(int begin = 0; begin < nums.size() - 2; begin++){//如果begin > 0,就不需要往后寻找了if(nums[begin] > 0){break;}//begin去重:不能简单地依据nums[begin] == nums[begin + 1]来去重,这样会漏掉-1,-1,2这种情况if(begin > 0 && nums[begin] == nums[begin - 1]){continue;}int left = begin + 1, right = nums.size() - 1;while(left < right){//对left和right的去重如果放在找到三元组之前,就会漏掉0,0,0这种情况int sum = nums[begin] + nums[left] + nums[right];if(sum < 0){left++;}else if(sum > 0){right--;}else{//因此left和right的去重应放在找到三元组之后while(left < right && nums[left] == nums[left + 1]){left++;}while(left < right && nums[right] == nums[right - 1]){right--;}res.push_back(vector<int>{nums[begin], nums[left], nums[right]});//找到之后左右指针同时移动left++;right--;}}}return res;}
};

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

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

相关文章

Node.js黑马时钟案例

先上没有使用node.js之前的html部分代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title></title><style>* {margin: 0;padding: 0;}html,body {height: 100%;overflow: hidden;backgrou…

Linux 常用命令汇总

1 linux定时任务 查看定时任务&#xff1a;crontab -l 每晚一点半执行定时任务&#xff1a; 30 1 * * * sh /var/lib/pgsql/pg_db_backup.sh >> /var/lib/pgsql/pg_db_backup.log 2>&1 配置定时任务&#xff1a;crontab -e 2 linux 内核版本查询 cat /etc/r…

Kafka-快速实战

Kafka介绍 ChatGPT对于Apache Kafka的介绍&#xff1a; Apache Kafka是一个分布式流处理平台&#xff0c;最初由LinkedIn开发并于2011年开源。它主要用于解决大规模数据的实时流式处理和数据管道问题。 Kafka是一个分布式的发布-订阅消息系统&#xff0c;可以快速地处理高吞吐…

JavaScript——基本语法

1.定义变量&#xff1a; 变量类型 变量名 变量值 var关键字声明变量 es6版本以上 var 可写可不写 <script>// 定义变量&#xff1a;变量类型 变量名 变量值 var关键字声明变量 es6版本以上 var 可写可不写var num 2;</script>2.条件控制 <script>var …

Java连接数据库的各种细节错误(细节篇)

目录 前后端联调&#xff08;传输文件&#xff09; ClassNotFoundException: SQLException: SQL语法错误: 数据库连接问题: 驱动问题: 资源泄露: 并发问题: 超时问题: 其他库冲突: 配置问题: 网络问题: SSL/TLS问题: 数据库权限问题: 驱动不兼容: 其他未知错误…

SIEM 解决方案的不同部署方式,如何选择SIEM 解决方案

安全信息和事件管理&#xff08;SIEM&#xff09;作为一种网络安全解决方案&#xff0c;是多种技术的融合&#xff0c;这些技术结合了包括安全信息管理和安全事件管理在内的流程。简单来说&#xff0c;SIEM 解决方案是一种重要的安全工具&#xff0c;它收集、存储和分析来自整个…

Impala4.x源码阅读笔记(二)——Impala如何高效读取Iceberg表

前言 本文为笔者个人阅读Apache Impala源码时的笔记&#xff0c;仅代表我个人对代码的理解&#xff0c;个人水平有限&#xff0c;文章可能存在理解错误、遗漏或者过时之处。如果有任何错误或者有更好的见解&#xff0c;欢迎指正。 Iceberg表是一种用于存储大规模结构化数据的…

Redis 环境搭建2

文章目录 第2关&#xff1a;使用 Redis 第2关&#xff1a;使用 Redis 本文是接着上篇文章写的第二关代码&#xff0c;部分人再进入第二关时不会保留第一关的配置的环境&#xff0c;可以通过下面一句代码进行检验。 redis-cli -p 7001 -c如果进入到了redis界面就是有环境&…

【开源】基于Vue+SpringBoot的教学资源共享平台

文末获取源码&#xff0c;项目编号&#xff1a; S 068 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S068。} 文末获取源码&#xff0c;项目编号&#xff1a;S068。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

矩母函数,概率生成函数, 随机变量的变换方法

这个标题真帅 Thanks Ni Zihan. 随机变量的变换方法总结概率生成函数 (probability-generating function, PGF)矩母函数&#xff08;Moment Generating Function &#xff0c; MGF&#xff09;矩母函数详细介绍 特征函数 Thanks Ni Zihan. 随机变量的变换方法总结 &#xff0…

网络安全——Iptables防DDoS攻击实验

一、实验目的要求&#xff1a; 二、实验设备与环境&#xff1a; 三、实验原理&#xff1a; 四、实验步骤&#xff1a; 五、实验现象、结果记录及整理&#xff1a; 六、分析讨论与思考题解答&#xff1a; 一、实验目的要求&#xff1a; 1、掌握常见DDoS攻击SYN Flood的攻击…

金数据企业版:广告推广效率提升的关键,无代码API集成与连接技术

深入理解无代码开发与API集成的重要性 在当今的电商竞争环境下&#xff0c;企业必须寻找提高效率和灵活性的办法。无代码开发平台&#xff0c;如金数据&#xff0c;提供了一种创新的方式来应对快速变化的市场需求&#xff0c;特别是在API集成方面。无代码开发意味着企业可以通…

Slate基础使用说明

目录 Slate基础使用说明 1. 简单教程 2. 要点说明 2.1 TCommands以及TCommands基类 2.2 FUICommandInfo 2.3 FUICommandList 2.4 FUIAction 2.5 UICommand 3. 代码源码 4. 工具使用 4.1 Display Ul Extension Points 4. 参考文章 Slate基础使用说明 1.…

C++1114新标准——统一初始化(Uniform Initialization)、Initializer_list(初始化列表)、explicit

系列文章目录 C11&14新标准——Variadic templates&#xff08;数量不定的模板参数&#xff09; C11&14新标准——Uniform Initialization&#xff08;统一初始化&#xff09;、Initializer_list&#xff08;初始化列表&#xff09;、explicit 文章目录 系列文章目录1…

快速解决Edge浏览器常见问题:完整教程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 一、Edge浏览器是什么&#xff1f; 二、常见的问题 1. DNS服务器出错 解决方案一&#xff1a;清除浏览器缓存和Cookie 2.网络问题 3.缓存和Cook…

网络安全等级保护V2.0测评指标

网络安全等级保护&#xff08;等保V2.0&#xff09;测评指标&#xff1a; 1、物理和环境安全 2、网络和通信安全 3、设备和计算安全 4、应用和数据安全 5、安全策略和管理制度 6、安全管理机构和人员 7、安全建设管理 8、安全运维管理 软件全文档获取&#xff1a;点我获取 1、物…

Spark RDD的转换

按颜色区分转换&#xff1a; 绿色是单 RDD 窄依赖转换黑色是多 RDD 窄依赖转换紫色是 KV 洗牌型转换黄色是重分区转换蓝色是特例的转换 单 RDD 窄依赖转换 MapPartitionRDD 这个 RDD 在第一次分析中已经分析过。简单复述一下&#xff1a; 依赖列表&#xff1a;一个窄依赖&…

【Java 基础】32 定时调度

文章目录 Timer 类创建 Timer注意事项 ScheduledExecutorService 接口创建 ScheduledExecutorService注意事项 选择合适的定时调度方式Timer 的适用场景ScheduledExecutorService 的适用场景 总结 在软件开发中&#xff0c;定时任务是一种常见的需求&#xff0c;用于周期性地执…

Java - Spring中Bean的循环依赖问题

什么是Bean的循环依赖 A对象中有B属性。B对象中有A属性。这就是循环依赖。我依赖你&#xff0c;你也依赖我。 比如&#xff1a;丈夫类Husband&#xff0c;妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。 Spring解决循环依赖的机理 Spring为什么可以解决set s…