leetcode 2563. 统计公平数对的数目 中等
给你一个下标从 0 开始、长度为 n
的整数数组 nums
,和两个整数 lower
和 upper
,返回 公平数对的数目 。
如果 (i, j)
数对满足以下情况,则认为它是一个 公平数对 :
0 <= i < j < n
,且lower <= nums[i] + nums[j] <= upper
示例 1:
输入:nums = [0,1,7,4,4,5], lower = 3, upper = 6 输出:6 解释:共计 6 个公平数对:(0,3)、(0,4)、(0,5)、(1,3)、(1,4) 和 (1,5) 。
示例 2:
输入:nums = [1,7,9,2,5], lower = 11, upper = 11 输出:1 解释:只有单个公平数对:(2,3) 。
提示:
1 <= nums.length <= 10^5
nums.length == n
-10^9 <= nums[i] <= 10^9
-10^9 <= lower <= upper <= 10^9
分析:先进行排序后,遍历数组。对于每一个 nums[i],可以使用二分查找找到一个区间 [l,r],使得所有的 i∈[l,r] 满足 lower−nums[j]≤nums[i]≤upper−nums[j]。具体来说,可以找到 ≤upper−nums[j] 的元素个数,减去 <lower−nums[j] 的元素个数,加入答案。
int find_index(int *nums,int numsSize,int target)
{int l=0,r=numsSize,m;while(l<r){int m=(l+r)/2;if(nums[m]>=target)r=m;else if(nums[m]<target)l=m+1;}return l;
}int cmp(const void *a,const void *b)
{return *(int*)a-*(int*)b;
}long long countFairPairs(int* nums, int numsSize, int lower, int upper) {long long ans=0;qsort(nums,numsSize,sizeof(int),cmp);for(int i=0;i<numsSize;++i){int l=find_index(nums,i,lower-nums[i]);int r=find_index(nums,i,upper-nums[i]+1);ans+=r-l;}return ans;
}