C++刷题 -- 哈希表

news2024/11/23 22:02:03

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;
    }
};

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

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

相关文章

springcloud多环境部署打包 - maven 篇

背景 在使用 springboot 和sringcloudnacos开发项目过程中&#xff0c;会有多种环境切换&#xff0c;例如开发环境&#xff0c;测试环境&#xff0c;演示环境&#xff0c;生产环境等&#xff0c;我们通过建立多个 yml 文件结合 profiles.active 属性进行环境指定&#xff0c;但…

Dockerfile创建镜像INMP+wordpress

Dockerfile创建镜像INMPwordpress 需要哪些呢&#xff1a; Nginx 172.111.0.10 docker-nginx Mysql 172.111.0.20 docker-mysql PHP 172.111.0.30 docker-PHP 开始实验&#xff1a; 创建各级目录&#xff0c;他们各自的包和配置文件必须要在同一目录下才可以生效&…

互联网加竞赛 LSTM的预测算法 - 股票预测 天气预测 房价预测

0 简介 今天学长向大家介绍LSTM基础 基于LSTM的预测算法 - 股票预测 天气预测 房价预测 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

STM32——串口实验(非中断)

需求&#xff1a; 接受串口工具发送的字符串&#xff0c;并将其发送回串口工具。 硬件接线&#xff1a; TX -- A10 RX -- A9 一定要记得交叉接线&#xff01;&#xff01; 串口配置&#xff1a; 1. 选定串口 2. 选择模式 异步通讯 3. 串口配置 4. 使用MicroLIB库 从…

PaddleOCR:超越人眼识别率的AI文字识别神器

在当今人工智能技术已经渗透到各个领域。其中&#xff0c;OCR&#xff08;Optical Character Recognition&#xff09;技术将图像中的文字转化为可编辑的文本&#xff0c;为众多行业带来了极大的便利。PaddleOCR是一款由百度研发的OCR开源工具&#xff0c;具有极高的准确率和易…

PyQt6 QStatusBar状态栏控件

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计44条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…

漂亮的WPF界面 流行的一个界面,向上悬浮的窗口,终于试成功了

目前随便打开个APP&#xff0c;就可以看到一个悬浮的窗口 今天测试一下目前流行的一个界面&#xff0c;向上悬浮的窗口&#xff0c;终于试成功了。看着还不错的。

【无标题】树莓派 4B 多串口配置

0. 实验准备以及原理 0.1 实验准备 安装树莓派官方系统的树莓派 4B&#xff0c;有 python 环境&#xff0c;安装了 serial 库 杜邦线若干 屏幕或者可以使用 VNC 进入到树莓派的图形界面 0.2 原理 树莓派 4B 有 UART0&#xff08;PL011&#xff09;、UART1&#xff08;mini UAR…

AI 绘画快速开始-StableDiffusionWebui

文章目录 介绍WebUI 的安装和部署参数介绍Prompt技巧初阶Prompt&#xff1a;直接描述的精细化二阶Prompt&#xff1a;巧用标签的扩展三阶Prompt&#xff1a;负面提示词的深入应用四阶Prompt&#xff1a;文本权重调整的细化引入 LoRA&#xff1a;模型特效的创新应用 案例-生成漫…

Armv8/Armv9从入门到精通-课程介绍

通知&#xff0c;Arm二期&#xff0c;咱们也有大合集PDF了&#xff0c;共计1587页&#xff0c;还未完成&#xff0c;后续持续更新和优化中。为了方便大家阅读、探讨、做笔记&#xff0c;特意整了此合集PPT&#xff0c;为了增加标签目录&#xff0c;还特意开了福兮阅读器会员。 …

Aduino实现音频频谱效果

看到这样一个效果,于是想用arduino实现类似效果。需要的组件如下 1 arduino开发板 2 音频传感器 3 灯带 接线图如图 代码如下 #include <EEPROM.h>#include <Adafruit_NeoPixel.h>#define PIN 2 // input pin Neopixel is attached to#define NUMPIXELS …

优雅玩转实验室服务器(三)vscode is all you need

在前两章解决了传输问题和连接问题后&#xff0c;我们紧接着遇到一个新的需求&#xff1a;我们需要coding呀&#xff0c;你当然可以说&#xff0c;我们可以用vim和对应的插件来搭建一个IDE呀&#xff0c;fine&#xff0c;我甚至可以给你推荐如下的教程&#xff1a; Vim 到底可…

Java - Math类的常用方法及练习

目录 1.1 概述 1.2 常用方法 ❓面试题&#xff1a;为啥Math.round(-1.5)-1? 1.1 概述 java.lang.Math 类包含用于执行基本数学运算的方法&#xff0c;如初等指数、对数、平方根和三角函数。类似这样的工具类&#xff0c;其所有方法均为静态方法&#xff0c;并且不会创建对象…

包装类 和 初阶泛型(详解)

【本节目标】 1. 以能阅读 java 集合源码为目标学习泛型 2. 掌握包装类 3. 掌握泛型 1. 包装类 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java给每个基本类型都对应了一个包装类型。 除了Integer和Charact…

MySQL笔记-第08章_聚合函数

视频链接&#xff1a;【MySQL数据库入门到大牛&#xff0c;mysql安装到优化&#xff0c;百科全书级&#xff0c;全网天花板】 文章目录 第08章_聚合函数1. 聚合函数介绍1.1 AVG和SUM函数1.2 MIN和MAX函数1.3 COUNT函数 2. GROUP BY2.1 基本使用2.2 使用多个列分组2.3 GROUP BY中…

云音乐大模型 Agent 探索实践

一. 前言 本篇文章介绍了大语言模型时代下的 AI Agent 概念&#xff0c;并以 LangChain 为例详细介绍了 AI Agent 背后的实现原理&#xff0c;随后展开介绍云音乐在实践 AI Agent 过程中的遇到的问题及优化手段。通过阅读本篇文章&#xff0c;读者将掌握业界主流的 AI Agent 实…

【C进阶】C程序是怎么运作的呢?-- 程序环境和预处理(下)

前言&#xff1a; 这是程序环境和预处理的下半篇文章。至此&#xff0c;关于c语言知识点:从编译到运行的过程已讲解完毕。传送&#x1f6aa;&#xff0c;上半篇&#xff1a; http://t.csdnimg.cn/hvxmr 本章涉及的知识点&#xff1a; 宏和函数对比、命名约定、#undef、命令行定…

【算法每日一练]-结构优化(保姆级教程 篇5 树状数组)POJ3067日本 #POJ3321苹果树 #POJ2352星星 #快排变形

目录 今天知识点 求交点转化求逆序对&#xff0c;每次操作都维护一个y点的前缀和 树的变动转化成一维数组的变动&#xff0c;利用时间戳将节点转化成区间 离散化数组来求逆序对数 先将y排序&#xff0c;然后每加入一个就点更新求一次前缀和 POJ3067&#xff1a;日本 思路&…

关于学习计算机的心得与体会

也是隔了一周没有发文了&#xff0c;最近一直在准备期末考试&#xff0c;后来想了很久&#xff0c;学了这么久的计算机&#xff0c;这当中有些收获和失去想和各位正在和我一样在学习计算机的路上的老铁分享一下&#xff0c;希望可以作为你们碰到困难时的良药。先叠个甲&#xf…

scala编码

1、Scala高级语言 Scala简介 Scala是一门类Java的多范式语言&#xff0c;它整合了面向对象编程和函数式编程的最佳特性。具体来讲Scala运行于Java虚拟机&#xff08;JVM)之上&#xff0c;井且兼容现有的Java程序&#xff0c;同样具有跨平台、可移植性好、方便的垃圾回收等特性…