代码随想录算法训练营第七天 | 454.四数相加II 、 383. 赎金信、15. 三数之和、18. 四数之和 、总结

news/2024/4/24 2:46:44/文章来源:https://blog.csdn.net/weixin_51233575/article/details/129150317

打卡第七天,还是哈希表。

今日任务

  • 454.四数相加II
  • 383.赎金信
  • 15.三数之和
  • 18.四数之和
  • 总结

454.四数相加II

在这里插入图片描述

代码随想录

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> myMap;for(int num1 : nums1) {for(int num2 : nums2) {myMap[num1 + num2]++;}}int cnt = 0;for(int num3 : nums3) {for(int num4 : nums4) {if(myMap.find(0 - (num3 + num4)) != myMap.end()) cnt += myMap[0 - (num3 + num4)];}}return cnt;}
};

本题解题步骤:

  • 首先定义 一个unordered_map,key放 num1 和 num2 两数之和,value 放 num1 和 num2 两数之和出现的次数。
  • 遍历 nums1 和 nums2 数组,统计两个数组元素之和,和出现的次数,放到map中。
  • 定义int变量count,用来统计 num1 + num2 + num3 + num4 = 0 出现的次数。
  • 在遍历大C和大D数组,找到如果 0 - (num3 + num4) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。
  • 最后返回统计值 count 就可以了

383.赎金信

在这里插入图片描述

我的题解

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {int hash[26] = {0};for(char c : ransomNote) {hash[c - 'a'] ++;}for(int c : magazine) {hash[c - 'a'] --;}for(int n : hash) {if(n > 0) return false;}return true;}
};

判断 ransomNote 能不能由 magazine 里面的字符构成,那就是说

  • 首先定义一个数组作为哈希表,因为字母只有26位,用数组就够了。
  • 然后哈希表统计一下 ransomNote 字母出现的个数。
  • 当哈希表中出现 magazine 的字母时候,减去 1。
  • 最后检查哈希表中,所有字母的值 有大于 0的,则结果返回false,反则 返回 true 。

代码随想录

// 时间复杂度: O(n)
// 空间复杂度:O(1)
class Solution {
public:bool canConstruct(string ransomNote, string magazine) {int record[26] = {0};//addif (ransomNote.size() > magazine.size()) {return false;}for (int i = 0; i < magazine.length(); i++) {// 通过recode数据记录 magazine里各个字符出现次数record[magazine[i]-'a'] ++;}for (int j = 0; j < ransomNote.length(); j++) {// 遍历ransomNote,在record里对应的字符个数做--操作record[ransomNote[j]-'a']--;// 如果小于零说明ransomNote里出现的字符,magazine没有if(record[ransomNote[j]-'a'] < 0) {return false;}}return true;}
};

15.三数之和

在这里插入图片描述

代码随想录

哈希法

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());// 找出a + b + c = 0// a = nums[i], b = nums[j], c = -(a + b)for (int i = 0; i < nums.size(); i++) {// 排序之后如果第一个元素已经大于零,那么不可能凑成三元组if (nums[i] > 0) {break;}if (i > 0 && nums[i] == nums[i - 1]) { //三元组元素a去重continue;}unordered_set<int> set;for (int j = i + 1; j < nums.size(); j++) {if (j > i + 2&& nums[j] == nums[j-1]&& nums[j-1] == nums[j-2]) { // 三元组元素b去重continue;}int c = 0 - (nums[i] + nums[j]);if (set.find(c) != set.end()) {result.push_back({nums[i], nums[j], c});set.erase(c);// 三元组元素c去重} else {set.insert(nums[j]);}}}return result;}
};

两层for循环就可以确定 a 和b 的数值了,可以使用哈希法来确定 0-(a+b) 是否在 数组里出现过,但是要处理三元组不重复问题,比较麻烦。

双指针法

Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort(nums.begin(), nums.end());// 找出a + b + c = 0// a = nums[i], b = nums[left], c = nums[right]for (int i = 0; i < nums.size(); i++) {// 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了if (nums[i] > 0) {return result;}// 错误去重a方法,将会漏掉-1,-1,2 这种情况/*if (nums[i] == nums[i + 1]) {continue;}*/// 正确去重a方法if (i > 0 && nums[i] == nums[i - 1]) {continue;}int left = i + 1;int right = nums.size() - 1;while (right > left) {// 去重复逻辑如果放在这里,0,0,0 的情况,可能直接导致 right<=left 了,从而漏掉了 0,0,0 这种三元组/*while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;*/if (nums[i] + nums[left] + nums[right] > 0) right--;else if (nums[i] + nums[left] + nums[right] < 0) left++;else {result.push_back(vector<int>{nums[i], nums[left], nums[right]});// 去重逻辑应该放在找到一个三元组之后,对b 和 c去重while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;// 找到答案时,双指针同时收缩right--;left++;}}}return result;}
};

18.四数之和

在这里插入图片描述

代码随想录

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> result;sort(nums.begin(), nums.end());for (int k = 0; k < nums.size(); k++) {// 剪枝处理if (nums[k] > target && nums[k] >= 0) {break; // 这里使用break,统一通过最后的return返回}// 对nums[k]去重if (k > 0 && nums[k] == nums[k - 1]) {continue;}for (int i = k + 1; i < nums.size(); i++) {// 2级剪枝处理if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {break;}// 对nums[i]去重if (i > k + 1 && nums[i] == nums[i - 1]) {continue;}int left = i + 1;int right = nums.size() - 1;while (right > left) {// nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) {right--;// nums[k] + nums[i] + nums[left] + nums[right] < target 会溢出} else if ((long) nums[k] + nums[i] + nums[left] + nums[right]  < target) {left++;} else {result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]});// 对nums[left]和nums[right]去重while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;// 找到答案时,双指针同时收缩right--;left++;}}}}return result;}
};

四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下标作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n2n^2n2),四数之和的时间复杂度是O( n3n^3n3) 。

总结

一般来说哈希表都是用来快速判断一个元素是否出现集合里。

对于哈希表,要知道哈希函数哈希碰撞在哈希表中的作用.

  • 哈希函数是把传入的key映射到符号表的索引上。
  • 哈希碰撞处理有多个key映射到相同索引上时的情景,处理碰撞的普遍方式是拉链法和线性探测法。

接下来是常见的三种哈希结构:

  • 数组
  • set(集合)
  • map(映射)

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

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

相关文章

【vue2每日小知识】实现directive自定义指令的封装与全局注册

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;将我们的自定义指令directive统一管理并批量注册 目录 一、directive自定义指令介绍 二…

DS期末复习卷(六)

一、选择题(30分) 1&#xff0e; 设一组权值集合W{2&#xff0c;3&#xff0c;4&#xff0c;5&#xff0c;6}&#xff0c;则由该权值集合构造的哈夫曼树中带权路径长度之和为&#xff08; D &#xff09;。 (A) 20 (B) 30 (C ) 40 (D) 45 W(23)*3(456)*245 2&#xff0e;执行一…

Python、Java、JavaScript、C、Go等编程语言如何实现“定时器”功能

这是CSDN平台2月推出的一个活动(活动链接为&#xff1a;CSDN 征文活动)&#xff0c;聊聊时间的话题&#xff0c;小编我也不知道有什么好聊的时间的话题&#xff0c;看了CSDN给出的部分话题上&#xff0c;有一个这样的话题&#xff0c;如何用各种编程语言实现“定时器”&#xf…

GUI可视化应用开发及Python实现

0 建议学时 4学时&#xff0c;在机房进行 1 开发环境安装及配置 1.1 编程环境 安装PyCharm-community-2019.3.3 安装PyQt5 pip install PyQt5-tools -i https://pypi.douban.com/simple pip3 install PyQt5designer -i https://pypi.douban.com/simple1.2 环境配置 选择“…

JVM13命令行

2. JVM 监控及诊断工具-命令行篇 2.1. 概述 简单命令行工具 在我们刚接触 java 学习的时候&#xff0c;大家肯定最先了解的两个命令就是 javac&#xff0c;java&#xff0c;那么除此之外&#xff0c;还有没有其他的命令可以供我们使用呢&#xff1f; 我们进入到安装 jdk 的…

【11】FreeRTOS的延时函数

目录1.延时函数-介绍2.相对延时函数-解析2.1函数prvAddCurrentTaskToDelayedList-解析2.3滴答定时器中断服务函数xPortSysTickHandler()-解析2.4函数taskSWITCH_DELAYED_LISTS() -解析3.延时函数-实验4.总结1.延时函数-介绍 函数描述vTaskDelay()相对延时xTaskDelayUntil()绝对…

CTFer成长之路之SSRF漏洞

SSRF漏洞CTF SSRF Training 题目描述: web容器中存在一个flag&#xff0c;mysql中存在一个管理员账号密码&#xff0c;其余容器中均没有特定flag mysql容器中内置 tcpdump vulnweb容器中内置一个 fpm.py 攻击脚本 docker-compose.yml version: "3" services:w…

Spring代理模式——静态代理和动态代理

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

笔记本电脑电池和充电器CE认证IEC62133测试

EC 符合性声明 - 您可以从品牌所有者或欧盟境内的商品官方进口商处获取此文件。证明您的商品经过检测符合下表所列标准的文件。您也可以从品牌所有者或欧盟境内的官方进口商处获取此文件。原品牌的笔记本电脑或手机&#xff08;如三星、苹果、戴尔、惠普等&#xff09;提供的原…

【验证码的识别】—— 点触式验证码的识别

一、前言 大家好&#xff0c;不知不觉的我来csdn已经又一周年了&#xff0c;在这一年里&#xff0c;我收获了很多东西&#xff0c;我是2022年2月22日入驻CSDN的&#xff0c;一开始只是为了方便浏览文章的&#xff0c;后来&#xff0c;我也有事没事发发文章&#xff0c;创作了1…

leetcode 1011. Capacity To Ship Packages Within D Days(D天内运送包裹的容量)

数组的每个元素代表每个货物的重量&#xff0c;注意这个货物是有先后顺序的&#xff0c;先来的要先运输&#xff0c;所以不能改变这些元素的顺序。 要days天内把这些货物全部运输出去&#xff0c;问所需船的最小载重量。 思路&#xff1a; 数组内数字顺序不能变&#xff0c;就…

Python 自动化测试必会技能板块—unittest框架

说到 Python 的单元测试框架&#xff0c;想必接触过 Python 的朋友脑袋里第一个想到的就是 unittest。的确&#xff0c;作为 Python 的标准库&#xff0c;它很优秀&#xff0c;并被广泛应用于各个项目。但其实在 Python 众多项目中&#xff0c;主流的单元测试框架远不止这一个。…

【C ++】C++入门知识(二)

C入门&#xff08;二&#xff09; 作者&#xff1a;小卢 专栏&#xff1a;《C》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 1.引用 1.1.引用的概念及应用 引用&#xff08;&&#xff09; 引用不是新定义一个变量&#xff0…

C语言格式化输出总结:%d,%c,%s,%f, %lf,%m.nd,%m.nf,%m.ns 以及sprintf函数

凡事发生必将有益于我&#xff0c;高手&#xff0c;从来都不仅仅是具备某种思维的人&#xff0c;而是那些具备良好学习习惯的人&#xff0c;成为高手&#xff0c;无他&#xff0c;手熟尔&#xff01;加油在最近的学习之中&#xff0c;对于格式化输出这个知识点&#xff0c;这里…

Spring自动装配的底层逻辑

Spring是如何自动装配Bean的&#xff1f;看源码一些自己的理解&#xff0c;如有错漏&#xff0c;请指正 使用Spring之前我们要先去web.xml中设置一下Spring的配置文件&#xff0c;在Spring的配置文件中&#xff0c;是通过component-scan扫描器去扫描base-package底下所有的类装…

google hacker语句

哎&#xff0c;我就是沾边&#xff0c;就是不打实战(&#xffe3;o&#xffe3;) . z Z 文章目录前言一、什么是谷歌Docker&#xff1f;二、受欢迎的谷歌docker语句谷歌docker的例子日志文件易受攻击的 Web 服务器打开 FTP 服务器SSH私钥电子邮件列表实时摄像机MP3、电影和 PDF…

Rocky 9.1操作系统实现zabbix6.0的安装部署实战

文章目录前言一. 实验环境二. 安装zabbix过程2.1. 安装zabbix源2.2 安装zabbix相关的软件2.3 安装数据库并启动2.4 开始初始化数据库&#xff1a;2.5 创建数据库实例及对应的用户2.6 导入官网提供的数据2.7 配置zabbix 服务的配置文件2.8. 启动服务2.9 从网页进行安装2.10 登陆…

从0开始学python -37

Python3 错误和异常 作为 Python 初学者&#xff0c;在刚学习 Python 编程时&#xff0c;经常会看到一些报错信息&#xff0c;在前面我们没有提及&#xff0c;这章节我们会专门介绍。 Python 有两种错误很容易辨认&#xff1a;语法错误和异常。 Python assert&#xff08;断…

单元测试面试秘籍分享

1. 什么是单元测试 “在计算机编程中&#xff0c;单元测试又称为模块测试&#xff0c;是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中&#xff0c;一个单元就是单个程序、函数、过程等&#xff1b;对于面向对象编程&#xff0c;最…

代码随想录NO49 | 动态规划 _LeetCode1143.最长公共子序列 1035.不相交的线 53. 最大子序和

动态规划 _LeetCode1143.最长公共子序列 1035.不相交的线 53. 最大子序和今天继续子序列问题&#xff01; 1143.最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符…