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 <= 105^55
nums.length == n
-109^99 <= nums[i] <= 109^99
-109^99 <= lower <= upper <= 109^99
先对nums排序,然后可以用相向双指针找出两数之和小于等于upper的数对数,然后再用相向双指针找出两数之和小于lower的数对数,两者相减即可:
class Solution {
public:long long countFairPairs(vector<int>& nums, int lower, int upper) {sort(nums.begin(), nums.end());return getNum(nums, upper) - getNum(nums, lower - 1);}long long getNum(vector<int>& nums, int target) {long long ret = 0;int left = 0;int right = nums.size() - 1;while (left < right) {if (nums[left] + nums[right] > target) {--right;// 如果两指针指向的数之和<=target// 则[left + 1, right]之间的每个数都可以和left组成和<=target的数对} else {ret += right - left;++left;}}return ret;}
};
如果nums的长度为n,则此算法时间复杂度为O(nlogn),瓶颈在排序处,双指针循环的时间复杂度为O(n);空间复杂度为O(logn),主要是排序的栈开销。