Every day a leetcode
题目来源:1995. 统计特殊四元组
解法1:遍历
最简单的方法就是枚举每一对符合要求的四元组(a, b, c, d),判断其中 a+b+c=d 的个数。
这种做法需要四层 for 循环。
根据提示:
四层也不会超时。
代码:
int countQuadruplets(int* nums, int numsSize){
int n=numsSize;
int count=0;
for(int a=0;a<n;a++)
{
for(int b=a+1;b<n;b++)
{
for(int c=b+1;c<n;c++)
{
for(int d=c+1;d<n;d++)
{
if(nums[a]+nums[b]+nums[c] == nums[d]) count++;
}
}
}
}
return count;
}
结果:
复杂度分析:
时间复杂度:O(n^4),n 为数组长度
空间复杂度:O(1)
解法2:hash
我们可以使用哈希表 hash 统计数组 nums[c+1] 到 nums[n−1] 中每个元素出现的次数。这样一来,我们就可以直接从哈希表中获得满足等式的 d 的个数,而不需要在 [c+1, n-1][c+1,n−1] 的范围内进行枚举了。
在枚举前三个下标 a, b, c 时,我们可以先逆序枚举 c。在 c 减小的过程中,d 的取值范围是逐渐增大的:即从 c+1 减小到 c 时,d 的取值范围中多了 c+1 这一项,而其余的项不变。因此我们只需要将 nums[c+1] 加入哈希表 hash 即可。
在这之后,我们就可以枚举 a, b 并使用哈希表 hash 计算答案。
代码:
#define MAX_HASH_LENGTH 500
int countQuadruplets(int* nums, int numsSize){
int ans=0;
int *hash;
hash=(int*)malloc(MAX_HASH_LENGTH*sizeof(int));
memset(hash,0,MAX_HASH_LENGTH*sizeof(int));
for(int c=numsSize-2;c>=2;c--)
{
hash[nums[c+1]]++;
for(int a=0; a<c;a++)
{
for(int b=a+1;b<c;b++)
{
ans+=hash[nums[a]+nums[b]+nums[c]];
}
}
}
free(hash);
return ans;
}
结果:
复杂度分析:
时间复杂度:O(n^3),n 为数组长度
空间复杂度:O(min(n,C)),其中 CC 是数组 nums 中的元素范围