链接 454. 四数相加 II - 力扣(Leetcode)
题目
思路
- 首先观察发现,四数相加可以拆解成两数相加,即只需要计算sum1+sum2是否等于0即可,在这道题中可以把时间复杂度从O(n^4)---->O(n^2)
- 需要用到哈希表(此处用结构体来实现), 首先需要声明一个unordered_map结构体,用于存放key跟value
(以下为原代码,此时我还未领悟到应该用结构体做。。。。)
int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
// int unordered_map[1000]={0};
int key1=0,key2=0;//记录a和b两数之和
int value[1000]={0};//记录a和b两数之和出现的次数
int count=0;//记录四数之和=0的次数
for(int i=0;i<nums1Size;i++)
{
for(int j=0;j<nums2Size;j++)
{
key1=nums1[i]+nums2[j];
value[key1]++;
key1=0;
}
}
for(int m=0;m<nums3Size;m++)
{
for(int n=0;n<nums4Size;n++)
{
key2=nums3[m]+nums4[n];
if(value[-key2])count++;
key2=0;
}
}
return count;
}
出现了超越整形范围的问题。。。
于是。。。
typedef struct hashtable
{
int key;//记录a和b两数之和
int value;//记录a和b两数之和出现的次数
UT_hash_handle hh;//①
}unordered_map;
学到了----关于UT_hash_handle hh:
hh是内部使用hash处理句柄,在使用过程中,只需要在结构体中定义一个UT_hash_handle类型的变量即可,不需要为该句柄变量赋值,但必须在该结构体中定义该变量 。
- 定义完哈希表结构体后最关键的疑问是如何把key跟value存入,并且记录多组数据
于是学习到哈希表 几个用法:
1.查找元素使用:HASH_FIND_INT():
//声明了一个返回值为hashTable类型指针的函数find,find函数的返回值为一个地址
struct hashTable* find(int key)
{
struct hashTable* temp;
HASH_FIND_INT(hashtable,&key,temp);//HASH_FIND_INT用法:参数1:哈希表;参数2:要查找的键值的地址(注意&);参数3:哈希表结构的结构体指针。
return temp;
//返回值:输入一个键值,哈希表则返回对应键的结构体,没有就返回NULL。
}
2.添加元素使用:HASH_ADD_INT():
HASH_ADD_INT用法:参数1:哈希表;参数2:要添加的键值;参数3:哈希表结构的结构体指针。
- 记录完sum1的数据,需要判断-sum2是否在结构体(key)中出现,有则count累计上此key(-sum2)对应的value值
for(int m=0;m<nums3Size;m++)
{
for(int n=0;n<nums4Size;n++)
{
int ikey=-nums3[m]-nums4[n];
unordered_map *find;
HASH_FIND_INT(myhash,&ikey,find);
if(find)count += find->value;
}
}
最终代码
typedef struct hashtable
{
int key;
int value;
UT_hash_handle hh;//①
}unordered_map;
int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
int key=0;//记录a和b两数之和
int value=0;//记录a和b两数之和出现的次数
int count=0;//记录四数之和=0的次数
typedef struct hashtable unordered_map;
unordered_map *myhash=NULL;//初始化哈希表
for(int i=0;i<nums1Size;i++)
{
for(int j=0;j<nums2Size;j++)
{
key=nums1[i]+nums2[j];
unordered_map *find=NULL;//初始化哈希表机构的结构体指针
HASH_FIND_INT(myhash,&key,find);
//首次myhash结构体为空,返回的find亦为空,故需要添加首次的数据
if(find)
{
find->value ++;
}else
{
unordered_map *new=(unordered_map*)malloc(sizeof(unordered_map));
new->key=key;
new->value=1;
HASH_ADD_INT(myhash,key,new);
}
}
}
for(int m;m<nums3Size;m++)
{
for(int n;n<nums4Size;n++)
{
key=-nums3[m]-nums4[n];
unordered_map *find=NULL;
HASH_FIND_INT(myhash,&key,find);
if(find)count += find->value;
}
}
return count;
}
时间复杂度O(n^2)
注意边写边检查细节!!!找错找了快一个小时才发现是for循环的初始值忘记写=0了,崩溃!!!太崩溃了!!!