统计公平数对的数目
难度:
标签:
题目描述
Given a 0-indexed integer array nums
of size n
and two integers lower
and upper
, return the number of fair pairs.
A pair (i, j)
is fair if:
0 <= i < j < n
, andlower <= nums[i] + nums[j] <= upper
Example 1:
Input: nums = [0,1,7,4,4,5], lower = 3, upper = 6 Output: 6 Explanation: There are 6 fair pairs: (0,3), (0,4), (0,5), (1,3), (1,4), and (1,5).
Example 2:
Input: nums = [1,7,9,2,5], lower = 11, upper = 11 Output: 1 Explanation: There is a single fair pair: (2,3).
Constraints:
1 <= nums.length <= 105
nums.length == n
-109 <= nums[i] <= 109
-109 <= lower <= upper <= 109
代码结果
运行时间: 163 ms, 内存: 29.2 MB
/*
* 思路:
* 1. 使用流来简化代码。
* 2. 通过两次迭代生成所有可能的数对。
* 3. 过滤出和在 lower 和 upper 之间的数对。
* 4. 计数公平数对的数量。
*/
import java.util.stream.IntStream;
public class FairPairsStream {
public int countFairPairs(int[] nums, int lower, int upper) {
return (int) IntStream.range(0, nums.length)
.flatMap(i -> IntStream.range(i + 1, nums.length)
.filter(j -> {
int sum = nums[i] + nums[j];
return sum >= lower && sum <= upper;
})
)
.count();
}
}
解释
方法:
这个题解采用了排序加双指针的方法。首先对数组进行排序,然后使用一个辅助函数fn来计算在某个目标值target下,数组中有多少对数的和小于等于target。在fn中,使用双指针left和right分别指向数组的开头和末尾,当nums[left] + nums[right]大于target时,说明需要减小和,所以将right指针左移;否则,说明找到了right - left对数的和小于等于target,将这些对数加入到计数中,并将left指针右移。最后,返回公平数对的数目,即在upper下的数对数目减去在lower-1下的数对数目。
时间复杂度:
O(n log n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算公平数对时选择使用排序加双指针的方法?这种方法与其他可能的解法相比有何优势或特点?
▷🦆
在使用双指针算法时,如何保证所有可能的符合条件的数对都被正确统计,而没有遗漏或重复计算?
▷🦆
函数`fn`在计算小于等于目标值的数对时,为什么在`nums[left] + nums[right] <= target`的情况下可以直接增加`right - left`个计数?这背后的逻辑是什么?
▷