LeetCode 2563. Count the Number of Fair Pairs

89 阅读1分钟

🔗 leetcode.com/problems/co…

题目

  • 给定数组 nums,寻找有多少个 (i, j) 对,满足 i < j && lower ≤ nums[i] + nums[j] ≤ upper

思路

  • 排序 nums,固定 nums[i],查找 j,满足 i < j && lower ≤ nums[i] + nums[j] ≤ upper 时,j 的最小值 min 和最大值 max,此时可以添加的 pair 对就是 max - min + 1 个
  • 查询 j 的最小值,就是查找 nums 中,nums[j] ≥ lower - nums[i] 的 j 的最小值,二分朝 left 逼近
  • 查询 j 的最大值,就是超着 nums 中,nums[j] ≤ upper - nums[i] 的 j 的最大值,二分朝 right 逼近

踩坑

  • 二分找 j 的最大值时,注意此时 mid 取值应该为 mid = ((l + r) >> 1) + ((l + r) & 1),注意括号,才能不死循环,找寻到 nums[j] ≤ upper - nums[i] 的最大值

代码

class Solution {
public:
    int lower_bound(vector<int>& nums, int i, int lower) {
        //printf("i %d lower ", i);
        lower = lower - nums[i];
        int l = i + 1;
        int r = nums.size()-1;
        if (nums[r] < lower) return -1;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (nums[mid] < lower) l = mid + 1;
            else r = mid;
        }
        return l;
    }

    int upper_bound(vector<int>& nums, int i, int upper) {
        //printf("i %d upper ", i);
        upper = upper - nums[i];
        int l = i + 1;
        int r = nums.size() -1;
        if (nums[l] > upper) return -1;
        while (l < r) {
            int mid = ((l + r) >> 1) + ((l + r) & 1);
            if (nums[mid] > upper) r = mid -1;
            else l = mid;
        }
        return l;
    }
    long long countFairPairs(vector<int>& nums, int lower, int upper) {
        sort(nums.begin(), nums.end());
        long long ans = 0;
        for (int i = 0; i < nums.size() - 1; i++) {
            int l = lower_bound(nums, i, lower);
            int r = upper_bound(nums, i, upper);
            if (l != -1 && r != -1) ans += r - l + 1;
        }
        return ans;

        
    }
};