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.mzph.cn/news/218058.shtml

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

相关文章

深入源码解析ArrayList:探秘Java动态数组的机制与性能

文章目录 一、 简介ArrayList1.1 介绍ArrayList的基本概念和作用1.2 与数组的区别和优势 二、 内部实现2.1 数据结构&#xff1a;动态数组2.2 添加元素&#xff1a;add()方法的实现原理2.3 扩容机制&#xff1a;ensureCapacity()方法的实现原理 三、 常见操作分析3.1 获取元素&…

0基础学习VR全景平台篇第127篇:什么是VR全景/720全景漫游?

“全景”作为一种表现宽阔视野的手法&#xff0c;在很久之前就得到了普遍的认同。北宋年间&#xff0c;由张择端绘制的《清明上河图》就是一幅著名的全景画。摄影术出现后&#xff0c;全景摄影也随之而生。 到今天&#xff0c;全景拍摄不再被专业摄影师所独享&#xff0c;广大…

C#的线程技术及操作(Thread类)

目录 一、线程基础 1.单线程 2.多线程 &#xff08;1&#xff09;多线程的缺点 &#xff08;2&#xff09;多线程的缺点 二、线程操作之Thread类 1. Thread类的相关方法和属性 &#xff08;1&#xff09;示例源码 &#xff08;2&#xff09;生成效果 2.创建线程Star…

代码随想录算法训练营 | day50 动态规划 123.买卖股票的最佳时机Ⅲ,188.买卖股票的最佳时机Ⅳ

刷题 123.买卖股票的最佳时机Ⅲ 题目链接 | 文章讲解 | 视频讲解 题目&#xff1a;给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔…

获取CAD图元名及图元信息(circle为例,用于选择集,对应dxf组码)

在CAD编程中往往需要用选择集&#xff0c;我们往往不知道相应图元对应的名称具体名字。比如我想选择所有的圆&#xff0c;ftype0,fdata应该是什么呢&#xff1f;是circle&#xff0c;acdbcircle&#xff0c;还是acadcircle? circle是一个对象&#xff0c;circle的vba类名为Ac…

SAP 散装物料简介

散装物料(Bulk Material),也叫做间接物料(Indirect Material),是一般企业在库存管理时常见的一种物料形式。散装物料专指那些价值小、消耗量大、消耗率高的物料件。这些物料组件同样服务于企业的生产活动,并且在企业的工作中心中被生产活动直接消耗(如螺丝钉、润滑油、…

海底数据中心:数据存储未来发展的新方向

随着信息技术的快速发展&#xff0c;数据需求量呈指数级增长&#xff0c;数据中心作为数据处理和存储的重要基础设施&#xff0c;其地位和作用愈发凸显。然而&#xff0c;传统的数据中心由于能耗大、碳排放高、土地占用等问题&#xff0c;已经难以满足可持续发展的需求。在此背…

Swin UNetR:把 UNet 和 Swin Transformer 结合

Swin UNetR&#xff1a;把 UNet 和 Swin Transformer 结合 网络结构使用指南 前置知识&#xff1a;Swin Transformer&#xff1a;将卷积网络和 Transformer 结合 Swin UNetR 结合 Swin Transformer 的上下文建模能力和 U-Net 的像素级别预测能力&#xff0c;提高语义分割任务的…

初始数据库 - 了解数据库

centos 7 版本当中安装 mysql 安装与卸载中&#xff0c;⽤⼾全部切换成为root&#xff0c;⼀旦 安装&#xff0c;普通⽤⼾是可以使用的。 卸载不需要的环境 首先&#xff0c;在安装之前&#xff0c;要先确定你当前系统当中是否已经有了mysql 的环境&#xff0c;如果你不想卸…

maui下sqlite演示增删改查

数据操作类 有分页 todoitemDatabase.cs&#xff1a; using SQLite; using TodoSQLite.Models;namespace TodoSQLite.Data {public class TodoItemDatabase{SQLiteAsyncConnection Database;public TodoItemDatabase(){}// 初始化数据库连接和表async Task Init(){if (Databa…

PPT插件-好用的插件-字距快速设置-大珩助手

字距快速设置 包含两端对齐、段首缩进、取消缩进、字间距、行间距、段后距 段首缩进 每次缩进两个字符&#xff0c;可对选中的文字、选中的多个文本对象两个层级操作 取消缩进 将缩进取消&#xff0c;可对选中的文字、选中的多个文本对象两个层级操作 字间距 预设了常用…

【GlobalMapper精品教程】065:连接SQL Server空间数据库并加载数据

Global Mapper是一个地图创建和编辑工具,无法像ArcGIS一样,基于SQL Server等大型关系型数据库。它本身也并不直接连接数据库。但是,Global Mapper可以与其他软件集成,以从数据库中获取数据并在地图上显示。本文讲述Global Mapper连接SLQ Server数据库的方法。 一、创建数据…

深入理解 Goroutines 和 Go Scheduler

本文将重点帮助您了解 Golang 中的 goroutines。Go 调度程序如何工作以在 Go 中实现最佳并发性能。我会尽力用简单的语言解释,这样你就可以理解了。 我们将介绍什么是操作系统中的线程和进程,什么是并发,为什么实现并发很难,以及 goroutines 如何帮助我们实现并发。然后,…

AtCoder ABC周赛2023 12/10 (Sun) D题题解

目录 原题截图&#xff1a; 题目大意&#xff1a; 主要思路&#xff1a; 注&#xff1a; 代码&#xff1a; 原题截图&#xff1a; 题目大意&#xff1a; 给定两个 的矩阵 和 。 你每次可以交换矩阵 的相邻两行中的所有元素或是交换两列中的所有元素。 请问要使 变换至…

JVM虚拟机系统性学习-垃圾回收器Serial、ParNew、Parallel Scavenge和Parallel Old

垃圾回收器 有 8 种垃圾回收器&#xff0c;分别用于不同分代的垃圾回收&#xff1a; 新生代回收器&#xff1a;Serial、ParNew、Parallel Scavenge老年代回收器&#xff1a;Serial Old、Parallel Old、CMS整堆回收器&#xff1a;G1、ZGC Serial&#xff1a;串行回收 Serial是…

Unity中实现ShaderToy卡通火(总结篇)

文章目录 前言一、把卡通火修改为后处理效果1、在Shader属性面板定义属性接收帧缓存纹理2、在片元着色器对其纹理采样后&#xff0c;与卡通火相加输出请添加图片描述 二、我们自定义卡通火1、修改 _CUTOFF 使卡通火显示在屏幕两侧2、使火附近屏幕偏红色 前言 在之前的文章中&a…

【IC验证】perl脚本——分析前/后仿用例回归情况

目录 1 脚本名称 2 脚本使用说明 3 nocare_list文件示例 4 脚本执行方法 5 postsim_result.log文件示例 6 脚本代码 1 脚本名称 post_analysis 2 脚本使用说明 help&#xff1a;打印脚本说明信息 命令&#xff1a;post_analysis help 前/后仿结束后&#xff0c;首先填…

计算机毕业设计 SpringBoot的企业内管信息化系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

首场“解数Talk” 直播来了——大模型语料数据联盟开源数据集解读

一、解数 Talk 介绍 为帮助广大开发者更好地了解大模型语料数据联盟发布的AI大模型语料数据&#xff0c;沟通大模型企业在AI视角下的数据需求&#xff0c;不断服务大模型产业生态和落地应用&#xff0c;联盟发起单位上海人工智能实验室联合成员单位共同打造“解数 Talk”系列直…

java系列-LinkedHashMap怎么实现LRU

1.定义变量accessOrder public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {final boolean accessOrder;public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {super(initialCapacity, loadFactor…