当前位置: 首页 > news >正文

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

454.四数相加II

题目链接:454.四数相加II

给你四个整数数组 nums1nums2nums3nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

文章讲解/视频讲解:https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html

思路

考虑采用哈希表来解决,题目给了四个数组,那么我们可以两两一组,遍历nums1[i] + nums2[j]的各种可能数值,将其存入hashmap中(记为hashmap1),即对每一个可能的相加数值,存储其出现过多少次。nums3[k] + nums4[l]的情况类似,也将相加结果存入hashmap中(记为hashmap2)。

然后遍历hashmap1,对于每一个key值p,在hashmap2中寻找key等于0 - p的键值对,如果找到了,则累加hashmap1[p] * hashmap2[-p]。

C++实现

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> hashmap1, hashmap2;for(int i = 0;i<nums1.size();i++){for(int j = 0;j<nums2.size();j++){hashmap1[nums1[i] + nums2[j]] += 1;}}for(int k = 0;k<nums3.size();k++){for(int l = 0;l<nums4.size();l++){hashmap2[nums3[k] + nums4[l]] += 1;}}int result = 0;for(auto p : hashmap1){if(hashmap2.find(-p.first) != hashmap2.end()){result += (p.second * hashmap2[-p.first]);}}return result;}
};

383. 赎金信

题目链接:383. 赎金信

给你两个字符串:ransomNotemagazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false

magazine 中的每个字符只能在 ransomNote 中使用一次。

文章讲解/视频讲解:https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html

思路

用哈希表来解决,用hashmap1统计magazine字符串中每个字符及其出现次数,然后用hashmap2统计resomNote字符串中每个字符及其出现次数。

对于hashmap2中的每个键值对,如果hashmap1中不存在对应的键,或者对应的值小于hashmap2中给定的值,说明不能满足题目给出的条件,反之则满足。

这里题目里说了两个字符串都由小写英文字母组成,因此开两个大小为26的数组即可表hashmap。

C++实现

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {vector<int> hashmap1(26, 0), hashmap2(26, 0);for(int i = 0;i<magazine.size();i++){hashmap1[magazine[i] - 'a'] += 1;}for(int i = 0;i<ransomNote.size();i++){hashmap2[ransomNote[i] - 'a'] += 1;}for(int i = 0;i<26;i++){if(hashmap1[i] < hashmap2[i]) return false;}return true;}
};

15. 三数之和

题目链接:15. 三数之和

编写一个算法来判断一个数 n 是不是快乐数。

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != kj != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请

你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

文章讲解/视频讲解:https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html

思路

n最大为3000,因此最多进行两层循环才能保证不超时。

可以考虑采用哈希表的方式解决。首先遍历一遍数组,用hashmap存下每个数值以及对应的下标index。

然后顺序进行两层遍历,在第二层遍历中,记录此时的二元组的值nums[i] + nums[j],然后在hashmap中寻找-nums[i] - nums[j]对应的下标,为了保证找到的三元组不重复,这里只记录下标值

大于j的可能情况。

上述思路考虑的是数组中每个数值不会重复的情况,而本题中的数值会重复。

因此hashmap中应存储的是每个数值以及对应的下标数组。

这种思路可以得到下标不重复的三元组。

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {unordered_map<int, vector<int>> hashmap;for(int i = 0;i<nums.size();i++){hashmap[nums[i]].emplace_back(i);}vector<vector<int>> results;for(int i = 0;i<nums.size();i++){for(int j = i + 1;j<nums.size();j++){int target = - nums[i] - nums[j];if(hashmap.find(target) == hashmap.end()) continue;for(int k = 0;k < hashmap[target].size();k++){if(hashmap[target][k] > j) results.push_back({i, j, hashmap[target][k]}); // 返回的是三元组的下标}}}return results;}
};

上面是上述思路的代码。

上述的思路中,只能保证找到的三元组index不重复,而不能保证每个三元组之间的数值不重复,举个例子:nums = [0, 0, 0, 0],如果保证三元组的index不重复,这里可以找出四个三元组组合,但是每个三元组都是[0, 0, 0],按照题意来说,只有一个不重复的三元组。

可以先对数组进行排序,然后再统计。这时可以用双指针的方式来解决。

还是采用两层循环。第一层循环i,如果发现nums[i] = nums[i - 1],则直接continue,因为如果nums[i] = nums[i - 1],此时找到的三元组必定重复。第二层循环,用双指针j和k代替,j指向当前二层遍历的第一个元素,k指向最后一个元素,同样的,如果发现nums[j] = nums[j - 1],直接continue。因为数组已经排好序,因此对于nums[j] + nums[k]的值,当j增加时变大,当k减少时变小。换成代码,如果nums[j] + nums[k] > -nums[i],则令k–,如果nums[j] + nums[k] < -nums[i],则令j++,如果相等,则说明找到了一组三元组,此时还要注意这次找到的三元组是否和上一次找到的三元组重复(防止nums[k]重复)。

C++实现

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());vector<vector<int>> results;for(int i = 0;i<nums.size();i++){if(i > 0 && nums[i] == nums[i - 1]) continue; // 保证不重复int target = -nums[i];int k = nums.size() - 1;for(int j = i + 1;j<nums.size();j++){if(j > i + 1 && nums[j] == nums[j - 1]) continue; // 保证不重复while(k > j && nums[j] + nums[k] > target) k--;if(k == j) break;if(nums[j] + nums[k] == target){if(results.size() > 0){vector<int> tmp = results[results.size() - 1];if(tmp[0] == nums[i] && tmp[1] == nums[j] && tmp[2] == nums[k]) continue; // 保证不重复}results.push_back({nums[i], nums[j], nums[k]});}}}return results;}
};

18. 四数之和

题目链接:18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

文章讲解/视频讲解:https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html

思路

和三数之和的思路是类似的,同样先排序,然后用双指针的方式消除一层循环。同样要注意去重。

用三层循环来遍历,第一层用i遍历时,注意要在nums[i] = nums[i - 1]时continue,因为如果nums[i] = nums[i - 1],此时找到的四元组必定重复。第二层用j遍历类似,也要在nums[j] = nums[j - 1]时continue。

然后使用我们的双指针k, l。k指向当前循环的第一个元素,l指向最后一个,同样地,要在nums[k] = nums[k - 1]时continue。

因为数组已经排好序,因此nums[k] + nums[l]的值随着k的增大而增大,随着l的减小而减小。

找到nums[k] + nums[l]正好等于target - nums[i] - nums[j]的组合,将其加入result中,这时也要检查result中的最后一个四元组是否和当前{nums[i], nums[j], nums[k], nums[l]}重复,这一步主要是避免nums[l]重复。

注意还有一个坑,数值不要超了int的边界。

C++实现

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {sort(nums.begin(), nums.end());vector<vector<int>> results;for(int i = 0;i<nums.size();i++){if(i > 0 && nums[i] == nums[i - 1]) continue; // 保证不重复for(int j = i + 1;j<nums.size();j++){if(j > i + 1 && nums[j] == nums[j - 1]) continue; // 保证不重复long long n_target = (long long)target - nums[i] - nums[j]; // 数值不要越界int l = nums.size() - 1;for(int k = j + 1;k<nums.size();k++){if(k > j + 1 && nums[k] == nums[k - 1]) continue; // 保证不重复while(l > k && nums[k] + nums[l] > n_target) l--;if(l == k) break;if(nums[k] + nums[l] == n_target){if(results.size() > 0){auto tmp = results[results.size() - 1];if(tmp[0] == nums[i] && tmp[1] == nums[j] && tmp[2] == nums[k] && tmp[3] == nums[l])continue; // 保证不重复}results.push_back({nums[i], nums[j], nums[k], nums[l]});}}}}return results;}
};

相关文章:

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

454.四数相加II 题目链接&#xff1a;454.四数相加II 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0…...

SpringBoot 3.2.0 版本 mysql 依赖下载错误

最近想尝试一下最新的 SpringBoot 项目&#xff0c;于是将自己的开源项目进行了一些升级。 JDK 版本从 JDK8 升级至 JDK17。SpringBoot 版本从 SpringBoot 2.7.3 升级到 SpringBoot 3.2.0 其中 JDK 的升级比较顺利&#xff0c;毕竟 JDK 的旧版本兼容性一直非常好。 但是在升级…...

内网穿透的应用-如何结合Cpolar内网穿透工具实现在IDEA中远程访问家里或者公司的数据库

文章目录 1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql小结 5. 固定连接公网地址6. 固定地址连接测试 IDEA作为Java开发最主力的工具&#xff0c;在开发过程中需要经常用到数据库&#xff0c;如Mysql数据库&#xff0c;但是在IDEA中只能连接本…...

ElasticSearch单机或集群未授权访问漏洞

漏洞处理方法&#xff1a; 1、可以使用系统防火墙 来做限制只允许ES集群和Server节点的IP来访问漏洞节点的9200端口&#xff0c;其他的全部拒绝。 2、在ES节点上设置用户密码 漏洞现象&#xff1a;直接访问9200端口不需要密码验证 修复过程 2.1 生成认证文件 必须要生成…...

【华为OD题库-097】最大岛屿体积-java

题目 题目描述 给你一个由大于0的数&#xff08;陆地)和0(水)组成的的二维网格&#xff0c;请你计算网格中最大岛屿的体积。陆地的数表示所在岛屿的体积。岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假…...

HTML中边框样式、内外边距、盒子模型尺寸计算(附代码图文示例)【详解】

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍HTML中边框样式、内外边距、盒子模型尺寸计算以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问…...

drf入门规范

一 Web应用模式 在开发Web应用中&#xff0c;有两种应用模式&#xff1a; 1.1 前后端不分离 1.2 前后端分离 二 API接口 为了在团队内部形成共识、防止个人习惯差异引起的混乱&#xff0c;我们需要找到一种大家都觉得很好的接口实现规范&#xff0c;而且这种规范能够让后端写…...

【微服务】springboot整合minio详解

目录 一、前言 二、Minio 概述 2.1 Minio简介 2.1 Minio特点 三、Minio 环境搭建 3.1 部署过程 3.1.1 拉取镜像 3.1.2 启动容器 3.1.3 访问web页面 四、Minio基本使用 4.1 基本概念 4.2 上传文件演示 4.3 用户管理 4.4 Java操作Minio 4.4.1 导入依赖 4.4.2 上传…...

减速机振动相关标准 - 笔记

参考标准&#xff1a;国家标准|GB/T 39523-2020 减速机的振动标准与发动机不同&#xff0c;摘引&#xff1a; 原始加速度传感器波形 可以明显看到调幅波 它的驱动电机是300Hz~2000Hz范围的。这个采样时间是5秒&#xff0c;看分辨率至少1024线。可分出500条谱线。 频谱部分 …...

【matlab】MATLAB 中的标量运算及实例

MATLAB 中的标量运算及实例 引言 在 MATLAB 中,标量是指只包含单个数值的变量或常量。尽管标量运算可能看似简单,但它在数值计算、数据处理和算法设计中扮演着重要的角色。本文将深入探讨 MATLAB 中的标量运算,介绍其基本操作和一些实例应用。 1. 标量运算的基本操作 标…...

java简易制作-王者荣耀游戏

一.准备工作 首先创建一个新的Java项目命名为“王者荣耀”&#xff0c;并在src下创建两个包分别命名为“com.sxt"、”com.stx.beast",在相应的包中创建所需的类。 创建一个名为“img”的文件夹来储存所需的图片素材。 二.代码呈现 package com.sxt; import javax…...

手撕分布式缓存---多节点的调取

经过上一个章节的学习&#xff0c;我们已经知晓了如何搭建了HTTP Server&#xff0c;通过HTTP协议与我们定义的路由&#xff0c;我们可以远程访问这个节点&#xff1b;基于这一点&#xff0c;我们可以部署多台实现了HTTP的缓存服务从而实现分布式的特性。这一章节我们要基于此背…...

C/C++编程中的算法实现技巧与案例分析

C/C编程语言因其高效、灵活和底层的特性&#xff0c;被广大开发者用于实现各种复杂算法。本文将通过10个具体的算法案例&#xff0c;详细探讨C/C在算法实现中的技巧和应用。 一、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序&#xff08;Bubble Sort&#xff09;是一…...

干货分享 | 如何在TSMaster中对常用总线报文信号进行过滤?

TSMaster软件平台支持对不同总线&#xff08;CAN、LIN、FlexRay&#xff09;的报文和信号过滤&#xff0c;过滤方法一般有全局接收过滤、数据流过滤、窗口过滤、字符串过滤、可编程过滤&#xff0c;针对不同的总线信号过滤器的使用方法也基本相同。今天重点和大家分享一下关于T…...

k8s链接数据库故障Waiting for table metadata lock

场景&#xff1a;早上来发现一个程序&#xff0c;链接mysql数据库有点问题&#xff0c;随后排查&#xff0c;因为容器在k8s里面。所以尝试重启了pod没有效果 一、重启pod: 这里是几种在Kubernetes中重启Pod的方法: 删除Pod,利用Deployment重建 kubectl delete pod mypodDepl…...

数字经济如何驱动企业高质量发展? ——核心机制、模式选择与推进路径

文章目录 每日一句正能量前言核心机制信息化和智能化作为数字经济的核心机制信息化和智能化如何提升企业生产效率和管理水平数据的获取、分析和利用对企业发展的影响 模式选择电子商务模式的选择共享经济模式的选择数据驱动的业务模式选择 推进路径建设数字化基础设施培养数字化…...

机器学习——支持向量机

目录 一、基于最大间隔分隔数据 二、寻找最大间隔 1. 最大间隔 2. 拉格朗日乘子法 3. 对偶问题 三、SMO高效优化算法 四、软间隔 五、SMO算法实现 1. 简化版SMO算法 2. 完整版SMO算法 3. 可视化决策结果 六、核函数 1. 线性不可分——高维可分 2. 核函数 …...

mq的作用

使用mq优点 mq是一种常见的中间件&#xff0c;在项目中经常用到&#xff0c;它具有异步、解耦、削峰填谷的作用。 异步 比如下单流程&#xff0c;A服务—>B服务&#xff0c;总的耗时是A耗时时间B耗时时间&#xff0c;而改为A—>mq---->B后&#xff0c;A发送mq后立刻…...

AUTOSAR组织引入了Rust语言的原因是什么?有哪些好处?与C++相比它有什么优点?并推荐一些入门学习Rust语言链接等

AUTOSAR(汽车开放系统架构)是一个由汽车制造商、供应商和其他来自电子、半导体和软件行业的公司组成的全球发展伙伴关系,自2003年以来一直致力于为汽车行业开发和引入开放、标准化的软件平台。 AUTOSAR 最近宣布成立一个新的工作组,用于探索在汽车软件中使用 Rust 编程语言…...

基于PyCharm实现串口GUI编程

工具效果如下如所示 下面简单介绍一下操作流程 1.打开PyCharm软件 2.创建一个工程 3.给该工程命名 4.在main.py里面黏贴如下的代码 # This is a sample Python script. # Press ShiftF10 to execute it or replace it with your code. # Press Double Shift to search everyw…...

【1.8计算机组成与体系结构】磁盘管理

目录 1.磁盘基本结构与存取过程1.1 磁盘基本结构1.2 磁盘的存取过程 2.磁盘优化分布存储3.磁盘单缓冲区与双缓冲区4.磁盘移臂调度算法 1.磁盘基本结构与存取过程 1.1 磁盘基本结构 磁盘&#xff1a;柱面&#xff0c;磁道&#xff0c;扇区。 1.2 磁盘的存取过程 存取时间寻…...

1663:【 例 1】取石子游戏 1

【题目描述】 有一种有趣的游戏&#xff0c;玩法如下&#xff1a; 玩家&#xff1a; 2 人&#xff1b; 道具&#xff1a; N 颗石子&#xff1b; 规则&#xff1a; 1、游戏双方轮流取石子&#xff1b; 2、每人每次取走若干颗石子&#xff08;最少取 1 颗&#xff0c;最多取…...

Django去访问web api接口Object of type Session is not JSON serializable

解决方案&#xff1a;settings.py中加入 &#xff1a;SESSION_SERIALIZER django.contrib.sessions.serializers.PickleSerializer 事由&#xff1a;Django去访问一个web api接口&#xff0c;两次连接之间需要通过Session()保持身份验证。 def sendCode(request): mobile jso…...

每日一题,二维平面

给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形&#xff0c;请你计算并返回两个矩形覆盖的总面积。 每个矩形由其 左下 顶点和 右上 顶点坐标表示&#xff1a; 第一个矩形由其左下顶点 (ax1, ay1) 和右上顶点 (ax2, ay2) 定义。 第二个矩形由其左下顶点 (bx1, …...

【jupyter notebook】jupyter notebook 调用另一个jupyter notebook 的函数

总结 使用 %run 魔法命令将 Notebook 转换为py文件使用 nbimporter 库手动复制代码优点notebook最前面加上即可最基本方法就跟导入py文件一样&#xff0c;不会被执行一遍快缺点所有的代码都会执行一遍修改原文件就要重新转换&#xff0c;且 从自定义的 .py 文件中导入函数时&a…...

Linux--学习记录(3)

G重要编译参数 -g&#xff08;GDB调试&#xff09; -g选项告诉gcc产生能被GNU调试器GDB使用的调试信息&#xff0c;以调试程序编译带调试信息的可执行文件g -g hello.c -o hello编译过程&#xff1a; -E&#xff08;预处理&#xff09; g -E hello.c -o hello.i-S&#xff08;编…...

自然语言处理阅读第一弹

Transformer架构 encoder和decoder区别 Embeddings from Language Model (ELMO) 一种基于上下文的预训练模型,用于生成具有语境的词向量。原理讲解ELMO中的几个问题 Bidirectional Encoder Representations from Transformers (BERT) BERT就是原生transformer中的Encoder两…...

Spring Boot+Mybatis设置sql日志打印

在全局配置文件添加以下内容&#xff1a;logging.level.com.demo.mapperdebug&#xff0c;com.demo.mapper&#xff1a;src下的mapper路径&#xff0c;debug&#xff1a;设置日志打印级别为debug&#xff0c;亦可设置为&#xff1a;ERROR、WARN、INFO application.properties …...

步进电机电流设置的3种方法

本文介绍步进电机电流设置的3种方法。 步进电机电流设置包括运行电流&#xff08;IRun&#xff09;和保持电流&#xff08;IHold&#xff09;2种。电机运行时需要有较大电流以保证有足够的力矩使物体运动&#xff0c;而停止的时候&#xff0c;为了减少电机发热及降低功耗&…...

uniapp-使用返回的base64转换成图片

在实际开发的时候 需要后端实时的给我返回二维码 他给我返回的是加密后的base64字符串 我需要利用这个base64转换到canvas画布上展示 或者以图片的形式展示在页面内 在canvas画布上展示 使用官方的uni.getFileSystemManager().writeFile()方法可将base64码转成的二维码显示在…...