[代码随想录打卡Day7] 454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

454.四数相加

思路:没有去重问题,使用化解法。先对a,b两个数组进行双层for循环遍历得到所有的a+b的值保存到map中,key是a+b的值,value存储出现的次数,然后双层for循环遍历c,d,查找0-(c+d)是否在map中,如果在map中就count+=value。
列一下JAVA,Python和C++代码。

class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {//先对a,b数组进行遍历保存a+b的值以及出现的此时int res = 0;Map<Integer, Integer> map = new HashMap<Integer, Integer>();//统计两个数组中的元素之和,同时统计出现的次数,放入到mapfor(int i : nums1){for(int j: nums2){int sum = i+j;map.put(sum, map.getOrDefault(sum, 0)+1);//getOrDefault应该如果存在就get相应的值,如果不存在就使用默认值,默认值设置是0}}//统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数for(int i : nums3){for(int j : nums4){res += map.getOrDefault(0-i-j,0);}}return res;}
}
class Solution(object):def fourSumCount(self, nums1, nums2, nums3, nums4):""":type nums1: List[int]:type nums2: List[int]:type nums3: List[int]:type nums4: List[int]:rtype: int"""hashmap = dict()for n1 in nums1:for n2 in nums2:if n1+ n2 in hashmap:hashmap[n1+n2] += 1else:hashmap[n1+n2] = 1#如果在就加1,不在就赋值为1#如果 -(n1+n2)存在于nums3和nums4,存入结果count = 0for n3 in nums3:for n4 in nums4:key = -n3-n4if key in hashmap:count += hashmap[key]return count
class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int, int> umap;//key:a+b的数值,value:a+b数值出现的次数//遍历大A和大B数组,统计两个数组元素之和,和出现的此时,放到map中for(int a: nums1){for(int b: nums2){umap[a+b]++;}}//把两个数的和放到map中相应的value++,统计次数int count = 0;//统计a+b+c+d=0出现的此时//再遍历大C和大D数组,找到如果0-(c+d)在map中出现过的话,就把map中key对应的value也就是出现次数统计出来。for(int c: nums3){for(int d: nums4){if(umap.find(0-(c+d))!=umap.end()){count += umap[0-(c+d)];}}}return count;}
};

II 383. 赎金信

和字母异位词太像了。就是判断条件变了,字母异位词是record数组中全是0,这个是先遍历magazine再遍历ransomNote要求record数组中大于等于0。
列一下JAVA和C++代码。

class Solution {public boolean canConstruct(String ransomNote, String magazine) {//这个题目说所有都是小写字母,所以用数组比较有效if(ransomNote.length() > magazine.length()){//如果长度直接不够就不用遍历了return false;}int[] record = new int[26];//遍历,遍历magazine中的字符如果存在就是把相应的字符的数量佳佳for(char c : magazine.toCharArray()){//变成char类型的数组record[c-'a']+=1;}for(char c: ransomNote.toCharArray()){record[c-'a'] -=1;}for(int i : record){if(i < 0){return false;}}return true;}
}
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++){//通过record数据记录magazine里各个字符出现的次数record[magazine[i] - 'a']++;//}//数组的索引是值,数组的值是出现的次数//感觉和字母异位词相似,就是看字母够不够用for(int j =0; j < ransomNote.length(); j++){//遍历ransomnOTE,在record里对应的字符个数做--操作record[ransomNote[j]-'a']--;if (record[ransomNote[j]-'a']<0){return false;}}return true;}
};

15. 三数之和

先排序,然后遍历i得到a,再i到num.size-1的区域引入对撞指针left,right就是在区间两端分别代表b,c。如果a+b+c>0就将right–,a+b+c<0就将left++,a+b+c=0就保存结果然后进行去重操作就是将left和right从当前位置移动到和当前数值相同的最靠近中间的位置,然后right–,left++进行下一轮寻找。
JAVA和C++写起来差不多,思想相同。
JAVA

class Solution {public List<List<Integer>> threeSum(int[] nums) {//双指针List<List<Integer>> result = new ArrayList<>();//这个就是生成结果列表,每个三元组的结果是有一个list组成的,多个List组成的result就是存放多个三元组的结果列表Arrays.sort(nums);//找出a+b+c=0//a = nums[i],b = nums[left],c = nums[right]for(int i = 0; i < nums.length; i++){//排序后如果第一个元素已经大于0,那么无论如何组合不可能凑成三元组,直接返回结果if(nums[i]>0){return result;}if(i >0 && nums[i] == nums[i -1]){//对a去重continue;}int left = i+1;int right = nums.length -1;while(right > left){int sum = nums[i] + nums[left] + nums[right];if(sum > 0){right--;}else if (sum < 0){left++;}else{result.add(Arrays.asList(nums[i], nums[left],nums[right]));//对b,c去重,下面两个while语句,把right移动到与当前值相同的最前面那个位置,left移动到与当前值相同的最后的一个位置while(right > left && nums[right] == nums[right-1]) right--;while(right > left && nums[left] == nums[left + 1]) left++;right--;left++;}}}return result;}
}

C++

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[left],c=nums[right]for(int i =0; i< nums.size(); i++){//如果排序之后第一个元素已经大于0, 那么无论如何组合都不可能凑成三元组,直接返回结果if(nums[i]>0){return result;}//去重a,a的循环中已经找到了所有的和a相加等于0的b,c的组合,所以如果有重复的,就把i++if(i > 0 && nums[i] == nums[i-1]){continue;}int left = i +1;int right = nums.size()-1;//就是把i当作遍历过的数从后面的数中寻找b,c使得a+b+c等于0while(right > left){//找到结果了再对b,c进行去重,为了防止直接去重把有重复数字的结果给Pass了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--;//这个是将right移动到最前面那个和right值相等的位置,while(right > left && nums[left] == nums[left + 1]) left++;//找到答案时, 双指针同时收缩、right--;left++;}}}return result;}
};

18. 四数之和

考虑到剪枝去重操作。明天再消化。列上C++代码。

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++){//二级剪枝处理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;}
};

参考的文章

  1. https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html
  2. https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html
  3. https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html
  4. https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html

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

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

相关文章

【系统架构设计师】2022年真题论文: 论区块链技术及应用(包括解题思路和素材)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2022年 试题3)解题思路区块链技术原理区块链技术的关键特性区块链技术的应用领域论文素材参考真题题目(2022年 试题3) 区块链作为一种分布式记账技术,目前已经被应用到了资产管理、物联网、医疗管理…

Kubernetes(K8s)相关漏洞介绍

Kubernetes&#xff08;K8s&#xff09;是一个开源的容器编排平台&#xff0c;用于自动化部署、扩展和管理容器化应用程序。然而&#xff0c;像任何复杂的软件系统一样&#xff0c;Kubernetes也存在一些安全漏洞。以下是一些已知的Kubernetes安全漏洞&#xff1a; Kubernetes镜…

C# 常用的测试框架合集

在 C# 开发中&#xff0c;拥有强大的测试框架是确保代码质量和稳定性的关键。本文将介绍一些 C# 中常用的测试框架&#xff0c;帮助你更好地进行单元测试、集成测试等各类测试工作。 一、NUnit 简介 NUnit 是一个广泛使用的开源测试框架&#xff0c;专为.NET 平台设计。它提供…

Obsidian vs Typora

引言 近来几日&#xff0c;自己也算是用了一段时间的Obsidian了&#xff0c;也是有资格来说一下使用感受了。当前感觉是自己未来很长一段时间将会一直使用Obsidian了。 Typora vs Obsidian Typora 优点 整体好看&#xff0c;简洁&#xff0c;所见即所得 缺点&#xff1a;…

Java 基于SpringBoot+Vue 的公交智能化系统,附源码、文档

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Spring Boot开发入门教程

简介 Spring Boot是一个开源的Java基础框架&#xff0c;用于创建独立、生产级的基于Spring框架的应用程序。通过Spring Boot&#xff0c;你可以轻松地创建独立的、生产级的Spring应用程序。 环境准备 Java开发环境&#xff1a;确保你的机器上安装了Java 8或更高版本。Maven…

科技资讯|谷歌Play应用商店有望支持 XR 头显,AR / VR设备有望得到发展

据 Android Authority 报道&#xff0c;谷歌似乎正在为其 Play 商店增加对 XR 头显的支持。该媒体在 Play 商店的代码中发现了相关的线索&#xff0c;包括一个代表头显的小图标以及对“XR 头显”的提及。 谷歌也可能改变了此前拒绝将 Play 商店引入 Meta Quest 头显的决定。今…

使用Python Flask实战构建Web应用

你是否曾想过&#xff0c;使用Python来快速搭建一个Web应用&#xff1f;Flask作为一个轻量级的Web框架&#xff0c;因其简单、灵活且高效&#xff0c;成为了很多开发者首选的工具。今天&#xff0c;就让我们一同走进Flask的世界&#xff0c;探索如何使用它轻松构建一个实战Web应…

map和set和pair

目录 一.序列式容器和关联式容器 一.set set类的介绍&#xff1a; Construct &#xff1a;set的初始化 insert&#xff1a;插入 ​编辑find&#xff1a;查找 erase&#xff1a;删除 set查找范围的函数&#xff1a;​编辑 二.map 2.1map介绍 2.2pair类型介绍 在map的i…

GA/T1400视图库平台EasyCVR视频分析设备平台微信H5小程序:智能视频监控的新篇章

GA/T1400视图库平台EasyCVR是一款综合性的视频管理工具&#xff0c;它兼容Windows、Linux&#xff08;包括CentOS和Ubuntu&#xff09;以及国产操作系统。这个平台不仅能够接入多种协议&#xff0c;还能将不同格式的视频数据统一转换为标准化的视频流&#xff0c;通过无需插件的…

HCIP(7)-边界网关协议BGP基本配置(对等体peer,宣告network,引入import)

边界网关协议&#xff08;Border Gateway Protocol&#xff0c;BGP&#xff09;是一种用来在路由选择域之间交换网络层可达性信息&#xff08;Network Layer Reachability Information&#xff0c;NLRI&#xff09;的路由选择协议。由于不同的管理机构分别控制着他们各自的路由…

GODOT 4 不用scons编译cpp扩展的方法

以terrain3d插件&#xff0c;Godot_v4.3 为例&#xff1a; 下载下来&#xff0c;先用scons编译一遍通过后&#xff0c;整个占用1GB&#xff0c;obj文件都生成在源码旁边&#xff0c;够乱。 scons 是跨平台的构建工具&#xff0c;但是需要需要写python脚本。流程比较莫名其妙…

KVM虚拟机的冷热迁移

首先了解在KVM&#xff08;Kernel-based Virtual Machine&#xff09;环境中&#xff0c;冷热迁移是指将虚拟机从一台主机迁移到另一台主机的过程&#xff0c;根据虚拟机是否需要停机&#xff0c;迁移分为热迁移和冷迁移&#xff1a; 冷迁移&#xff08;Cold Migration&#x…

掌握ElasticSearch(八):聚集、文档间的关系

文章目录 一、聚集聚集类型示例 二、文档间的关系1. 对象类型&#xff08;Object Type&#xff09;2. 嵌套文档&#xff08;Nested Documents&#xff09;定义嵌套字段索引嵌套文档查询嵌套文档 3. 父子关系&#xff08;Parent-Child Relationship&#xff09;定义父子关系索引…

sqlalchemy进阶使用

from sqlalchemy import create_engine# 替换为你的MySQL数据库信息 username root password 123456 host localhost # 例如&#xff1a;localhost 或 127.0.0.1 port 3306 # 通常是 3306 database ee# 创建连接引擎 engine create_engine(fmysqlpymysql://{username}:…

AIGC时代LaTeX排版的应用、技巧与未来展望

文章目录 一、LaTeX简介与基础设置二、常用特殊符号与公式排版三、图片与表格的插入与排版四、自动编号与交叉引用五、自定义命令与样式六、LaTeX在AIGC时代的应用与挑战七、LaTeX的未来展望《LaTeX 入门实战》内容简介作者简介目录前言/序言读者对象本书内容充分利用本书 在AI…

Ansible 部署应用

Ansible Ansible 是基于 Python 开发&#xff0c;集合了众多优秀运维工具的优点&#xff0c;实现了批量运行命令、部署程序、配置系统等功能的自动化运维管理工具。默认通过 SSH 协议进行远程命令执行或下发配置&#xff0c;无需部署任何客户端代理软件&#xff0c;从而使得自动…

centos7 rpm -ivh *.rpm --nodeps 会导致有哪些问题?

使用 rpm -ivh *.rpm --nodeps 命令来安装 RPM 包会忽略所有依赖关系&#xff0c;这可能导致以下几种问题&#xff1a; 缺少依赖库&#xff1a; ● 如果某个包依赖的库文件没有安装&#xff0c;那么该包可能无法正常运行。例如&#xff0c;如果 keepalived 依赖于 libnetsnmp.s…