一、题目描述
二、思路
暴力解法的话时间复杂度是O(n^4),但如果先记录nums1与nums2中各元素之和(a+b)与和的个数(value),再去判断是否存在nums3与nums4各元素的和(c+d)能与上述记录到的值相加等于0,若可以的话则更新返回元素count的值,这样做下来时间复杂度仅为O(n^2)。
三、解题过程
-
定义hashMap结构体
- key用来储存(a + b),value来储存(a + b)出现的次数:
typedef struct {
int key;
int value ;
UT_hash_handle hh;
} map;
map* hashMap = NULL;
-
实现插入接口函数
- 若(a+b)的值之前没出现过,则向哈希表中插入key为(a+b)、value为1的结构体;若(a+b)的值之前出现过,则将哈希表中key为(a+b)的结构体的value数值加一:
void hashMapAdd (int key) {
map *s;
HASH_FIND_INT(hashMap, &key, s);
if(!s) {
s = (map*)malloc(sizeof(map));
s -> value = 1;
s -> key = key;
HASH_ADD_INT(hashMap, key, s);
} else (s -> value) ++;
}
-
实现查找接口函数
map* hashMapFind (int key) {
map* s;
HASH_FIND_INT(hashMap, &key, s);
return s;
}
-
fourSumCount函数
-
更新哈希表为NULL
hashMap = NULL;
-
记录nums1与nums2中各元素之和(a+b)与和的个数(value)
int i, j;
int count = 0;
for (i = 0; i < nums1Size; i ++) {
for (j = 0; j < nums2Size; j ++) {
hashMapAdd(nums1[i] + nums2[j]);
}
}
-
判断是否存在nums3与nums4各元素的和(c+d)能与上述记录到的值相加等于0
- 若可以的话则更新返回元素count的值:
for (i = 0; i < nums3Size; i ++) {
for (j = 0; j < nums4Size; j ++) {
map* find = hashMapFind(0 - (nums3[i] + nums4[j]));
if (find) {
count += (find -> value);
}
}
}
-
返回count值
return count;
四、代码
typedef struct {
int key;
int value ;
UT_hash_handle hh;
} map;
map* hashMap = NULL;
void hashMapAdd (int key) {
map *s;
HASH_FIND_INT(hashMap, &key, s);
if(!s) {
s = (map*)malloc(sizeof(map));
s -> value = 1;
s -> key = key;
HASH_ADD_INT(hashMap, key, s);
} else (s -> value) ++;
}
map* hashMapFind (int key) {
map* s;
HASH_FIND_INT(hashMap, &key, s);
return s;
}
int fourSumCount(int* nums1, int nums1Size, int* nums2, int nums2Size, int* nums3, int nums3Size, int* nums4, int nums4Size){
hashMap = NULL;
int i, j;
int count = 0;
for (i = 0; i < nums1Size; i ++) {
for (j = 0; j < nums2Size; j ++) {
hashMapAdd(nums1[i] + nums2[j]);
}
}
for (i = 0; i < nums3Size; i ++) {
for (j = 0; j < nums4Size; j ++) {
map* find = hashMapFind(0 - (nums3[i] + nums4[j]));
if (find) {
count += (find -> value);
}
}
}
return count;
}
时间复杂度:O(n^2),空间复杂度O(n^2)