当前位置: 首页 > 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…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...