文章归档算法题解

leetcode-2563. 统计公平数对的数目

2563. 统计公平数对的数目

题目要统计和落在 [lower, upper] 内的数对。统计的是不同位置之间的配对数量,重新排列元素不会改变这个数量,所以可以先排序,再利用二分查找确定范围。

由 lower≤x+y≤upperlower\le x+y\le upper 可以得到 lower−x≤y≤upper−xlower-x\le y \le upper-x。对于位置 i 上的 x,只在 i+1 到 n-1 的后缀中查找,避免同一对被重复统计。Python 中的 bisect 返回右侧插入位置,因此 L=bisect(a,lower-x-1),R=bisect(a,upper-x)-1,两次查找都要传入起点 i+1。闭区间 [L, R] 内有 R-L+1 个符合条件的元素。

Python 代码如下:

Python
from bisect import *

class Solution:
    def countFairPairs(self, a: List[int], lower: int, upper: int) -> int:
        a.sort()
        res = 0
        for i, x in enumerate(a):
            L = bisect(a, lower - x - 1, i + 1)
            R = bisect(a, upper - x, i + 1) - 1
            res += R - L + 1
        return res

C++ 代码如下:

C++
class Solution {
public:
    long long countFairPairs(vector<int>& nums, int lower, int upper) {
        sort(nums.begin(), nums.end());
        long long res = 0;
        for (int i = 0; i < nums.size(); i++) {
            int L = upper_bound(nums.begin() + i + 1, nums.end(),
                                lower - nums[i] - 1) -
                    nums.begin();
            int R =
                upper_bound(nums.begin() + i + 1, nums.end(), upper - nums[i]) -
                nums.begin() - 1;
            res += R - L + 1;
        }
        return res;
    }
};

C++ 的 upper_bound 返回迭代器。要计算数组下标,可以将它减去 nums.begin(),再做下标的加减;如果只需要统计区间长度,也可以直接计算两个边界迭代器之差。

谢谢你读到这里。 ✧
搜索文章

输入关键词,找一篇想读的手记。

算法专题leetcode双指针经典练习题算法题解leetcode-1438. 绝对差不超过限制的最长连续子数组算法题解leetcode-179. 最大数算法题解leetcode-239. 滑动窗口最大值算法题解leetcode-136. 只出现一次的数字算法专题leetcode动态规划基础练习题算法专题leetcode二叉树基础练习题算法专题leetcode数组双指针练习题算法专题leetcode滑动窗口练习题算法专题leetcode链表双指针练习题算法题解洛谷-P1029 [NOIP 2001 普及组] 最大公约数和最小公倍数问题算法题解leetcode-1979. 找出数组的最大公约数算法题解洛谷-B3634 最大公约数和最小公倍数算法题解洛谷-P10424 [蓝桥杯 2024 省 B] 好数算法题解洛谷-P8716 [蓝桥杯 2020 省 AB2] 回文日期自动化脚本Dr.com校园网自动登录方案算法题解leetcode-2226. 每个小孩最多能分到多少糖果算法题解leetcode-2563. 统计公平数对的数目算法题解leetcode-1.两数之和算法题解洛谷-P8218 【深进1.例1】求区间和
在这座小岛上,慢慢找。ESC 关闭