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中,将遍历过的元素插入map
                nums_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;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity中实现ShaderToy卡通火(原理实现篇)

文章目录 前言一、我们在片元着色器中&#xff0c;实现卡通火的大体框架1、使用 noise 和 _CUTOFF 判断作为显示火焰的区域2、_CUTOFF &#xff1a; 用于裁剪噪波范围的三角形3、noise getNoise(uv, t); : 噪波函数 二、顺着大体框架依次解析具体实现的功能1、 uv.x * 4.0; : …

如何进行产品数据分析一——移动应用APP分析方法

如何进行产品数据分析 产品的定义产品分析的构成移动应用APP分析方法AARRR1.流量拆解DAUMAU活跃率拆解流量深度 2.流量引入反作弊算法识别系统&#xff08;量&#xff09;拉新质量评估体系&#xff08;质&#xff09;渠道价值评估体系&#xff08;值&#xff09; 3.流量输出 产…

[MySQL]事务原理之redo log,undo log

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、log日志文件 &#x1f4d5; 事务执行流程 &#x1f4d5; redo log &#x1f4d5; undo log 二、总结 &#x1f440;再来一遍ACID 1. 原子性&#xff1a;原子性确保事务作为一个整体执行&#xff0c;要么…

D4140交流插座电器漏电断路器的低功耗控制芯片,内置桥式整流器漏电灵敏度可调,采用SOP8和DIP8 的封装形式

D4140 是一种用于交流插座电器漏电断路器的低功耗控制器。这些设备可以检测到接地的危险电流路径&#xff0c;例如设备掉进水中。在发生有害或致命的电击之前&#xff0c;断路器会断开线路。内置有整流桥&#xff0c;齐纳管稳压器&#xff0c;运算放大器&#xff0c;电流基准&a…

【数学建模美赛M奖速成系列】报名流程与论文的基本格式

数学建模美赛M奖速成系列 写在前面报名方式1.官网直接报名2.赛氪软件辅助报名 论文的基本格式摘要模型建立模型求解结果分析与检验模型评价 竞赛的基本注意事项1. 选题后查找资料2. 写作能力和编程能力 历年优秀论文标题与摘要简明扼要善用图表 最后 写在前面 最近&#xff0c…

【Docker】学习笔记(一)三剑客之 docker engine仓库、镜像与容器的基本操作

docker engine安装 ubuntu20.04安装docker教程 docker核心架构 镜像&#xff08;image&#xff09; 一个镜像就代表一个软件服务&#xff08;ubuntu镜像、mysql镜像、redis镜像、mq镜像&#xff09;只读 远程中心仓库&#xff08;repository&#xff09; 中心仓库用来集中存储…

5.1CPU的功能和结构

CPU的功能 1.指令控制。 完成取指令、分析指令和执行指令的操作&#xff0c;即程序的顺序控制。 ⒉操作控制。 一条指令的功能往往是由若干操作信号的组合来实现的。CPU管理并产生由内存取出的每条指令的操作信号&#xff0c;把各种操作信号送往相应的部件&#xff0c;从而控制…

微信小程序:上传图片到别的域名文件下

效果 wxml <!-- 上传照片 --> <view class"addbtn"><view classpic name"fault_photo" wx:for"{{imgs}}" wx:for-item"item" wx:key"*this"><image classweui-uploader_img src"{{item}}"…

程序员必须知晓的11个C++要点-供大家学习研究参考

要点汇集C书中或网站上无法找到的&#xff0c;如&#xff1a;指向成员的指针&#xff0c;这是许多资料中都不愿提到的地方&#xff0c;也是经常出错的地方。希望对大家学习研究有帮助。 要点1: <iostream.h> 还是 <iostream>? 要点2&#xff1a;用引用传递参数时…

若依 ruoyi-vue3+ts-plus+ 宇道 yudao-ruoyi-vue-pro前端显示部门名称

想在 index.vue 上显示列表里对应的部门名称 效果 引入dept import * as DeptApi from "/api/system/dept"; 初始化时 /** 初始化 **/ onMounted(async () > {getList();deptNameList.value await DeptApi.getSimpleDeptList(); }) 加载id 对应的部门名称 …

网络推理之深度学习推理框架

如何选择深度学习推理框架&#xff1f; PyTorch vs LibTorch&#xff1a;网络推理速度谁更快&#xff1f; 高质量C进阶[2]&#xff1a;如何让线性代数加速1000倍&#xff1f; TensorRT: ONNX:

AI日报:人工智能与新材料的发现

文章目录 总览人工智能正在革命性地发现新的或更强的材料&#xff0c;这将改变制造业。更坚韧的合金问题研究解决方案 新材料人工智能存在的挑战方法探索 日本的研究人员正在使用人工智能制造更强的金属合金或发现新材料&#xff0c;并彻底改变制造过程 总览 日本的研究人员开…

【C】⽂件操作

1. 为什么使⽤⽂件&#xff1f; 如果没有⽂件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运⾏程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进⾏持久化…

鸿蒙原生应用/元服务开发-Stage模型能力接口(二)

ohos.app.ability.AbilityConstant (AbilityConstant)一、说明 AbilityConstant提供Ability相关的枚举&#xff0c;包括设置初次启动原因、上次退出原因、迁移结果、窗口类型等。本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口…

【Java 基础】32 定时调度

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

替代升级虚拟化 | ZStack Cloud云平台助力康恩贝核心业务上云

数字经济正加速推动各行各业的高质量升级发展&#xff0c;云计算是数字经济的核心底层基础设施。作为云基础软件企业&#xff0c;云轴科技ZStack 坚持自主创新&#xff0c;自研架构&#xff0c;产品矩阵可全面覆盖数据中心云基础设施&#xff0c;针对虚拟化资源实现纳管、替代和…

大数据技术之Shell(超级详细)

大数据技术之Shell&#xff08;超级详细&#xff09; 第1章 Shell概述 Shell 是一种脚本语言&#xff0c;用于在操作系统的命令行界面&#xff08;CLI&#xff09;下执行命令和脚本。在大数据领域&#xff0c;Shell 脚本常用于编写数据处理和分析任务的自动化脚本&#xff0c…

java swing 药品销售系统 mysql

数据库 查询药品&#xff1a; 出售药品&#xff1a; 查询客户信息&#xff1a; 查询订单信息&#xff1a;

Next.js ts redux/toolkit状态管理

目录 介绍 安装依赖 初始化store 1、在src下创建store文件夹&#xff0c; 2、创建最简单的slice切片 3、创建入口文件index.ts 4、创建hooks.ts 在_app.tsx中注入store tsx中使用store payload createAsyncThunk 效果 介绍 reduxjs/toolkit是Redux 官方提供的一个…

Axure元件基本介绍进阶

Axure元件基本介绍进阶 1.Axure元件基本介绍1.在 Axure 中&#xff0c;元件是构建原型的基本构成单元&#xff0c;能够帮助设计师快速创建、重复使用和管理设计元素。以下是 Axure 中元件的基本介绍&#xff1a;1.基本元件&#xff1a; 2.基本元件的使用一.【举例说明】积木&am…