小白跟随卡哥刷题第十一天(hash表部分)

一、前言

在此先向各位uu说声抱歉,端午节本来只打算休息一天的,结果由于某些原因中间又耽误了两天,今天才重新开始了学习、刷题,向uu们说声抱歉。那么就说说今天的题目吧,今天的题目不算是很难,即不使用map等hash表也可以做出来,只是要超时,具体的放到下面来说吧,

二、题目(力扣第454题—四数相加||. - 力扣(LeetCode)

给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

示例一:

输入:

  • A = [ 1, 2]
  • B = [-2,-1]
  • C = [-1, 2]
  • D = [ 0, 2]

输出:

2

解释:

两个元组如下:

  1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
  2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

三、题解

这个题看着是从四个数组选择不同元素组成相加等于0即可,因此最简单的暴力解法就是四重循环(简单、粗暴)但是会超时,因为时间复杂度实在是太大了(O(n^{4}))力扣这里会报超时的,因此这个办法在此处不行,因此这里需要使用到map,因为这道题目是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,然后将四个数组分成两个部分,前两个数组一部分,后两个数组一部分,两者想加等于0即可。话不多说,上代码具体来讲讲。(对了卡哥的讲解也放在这里了代码随想录

代码:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
	int co=0;//存储有多少个
	unordered_map<int,int> unmap;
	for(auto a:nums1){//遍历循环nums1、nums2两个数组
		for(auto b:nums2){
			unmap[a+b]++;
		}
	}
	for(auto c:nums3){
		for(auto d:nums4){
			if(unmap.find(0-(c+d))!=unmap.end()){
				co+=unmap[0-(c+d)];
			}
		} 
	}
	return co;
}

接下来就具体讲讲代码部分

定义的map的key(类似于数组下标)来存放两个数组的元素相加的值,而map中的value(类似于数组下标代表的值)来存放两个元素相加的值出现的次数。

这里的循环是c++11里面比较常见的循环方式,以前也讲过,大家可以尝试用这个来替代以前的for循环(因为这种循环是使用迭代器实现的,对于set、map这种不能使用下标的都是可以来“遍历”其中的元素的)

for(auto a:nums1)

使用a和b来遍历nums1和nums2中的元素,用map的key来存放a、b和,map的value来存放a、b和的值出现的次数。

for(auto a:nums1){//遍历循环nums1、nums2两个数组
		for(auto b:nums2){
			unmap[a+b]++;//map中的key来存放a+b的值,map中的value来存放a+b出现的次数
		}
	}

这里的c和d就是后面两个数组nums3、nums4的遍历变量(与a和b的作用一样),主要讲讲下面两行代码的含义。使用find函数可以简便的搜索map中是否有该元素存在,这里的0-(c+d)就等于a+b的值(因为a+b+c+d=0,将四个数组分成两部分,a+b一部分先存入map中,c+d一部分用来检查map中是否有a+b这个值的元素存在,((0-c+d)来检查))。若存在该元素,则将该元素对应出现的次数加到co上即可。

if(unmap.find(0-(c+d))!=unmap.end())
				co+=unmap[0-(c+d)];

四、后记

find函数在map、set中是非常好用的,来检查是否存在该元素。大家要多多尝试使用。然后就是遍历的形式for(auto it:nums)这种遍历对任何数据结构都是适用的,希望大家也都适用这种遍历形式。最后希望大家多多练习,不要像我三天打鱼两天晒网(我错了www)。各位加油加油,我们都有光明的未来!

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值