2563. 统计公平数对的数目

123 阅读1分钟

题目:
给你一个下标从 0 开始、长度为 n 的整数数组 nums ,和两个整数 lower 和 upper ,返回 公平数对的数目 。

如果 (i, j) 数对满足以下情况,则认为它是一个 公平数对 :

  • 0 <= i < j < n,且
  • lower <= nums[i] + nums[j] <= upper

算法:
方法一: 排序+二分查找
思路对了,没写出来代码

func countFairPairs(nums []int, lower int, upper int) int64 {
    sort.Ints(nums)
    n := len(nums)
    ans := int64(0)

    // 不设置i < n为了过[0,0,0,0,0]这个案例
    for i := 0; i < n - 1; i ++ {
        // 大于小于关系理不清楚是吧,ok,我用笨办法行了吧
        left := findGreaterEqualThan(nums, lower - nums[i], i + 1, n - 1)
        right :=  findLessEqualThan(nums, upper - nums[i], i + 1, n - 1)
        // 上面已经满足了lower <= nums[left] + nums[i], nums[right] + nums[i] <= lower
        // 再检查是否满足lower <= nums[i] + nums[right] , nums[i] + nums[left] <= upper 
        if lower <= nums[i] + nums[right]  && nums[i] + nums[left] <= upper {
            fmt.Println(nums[i], nums[left], nums[right], right - left + 1)
            ans = ans + int64(right - left + 1) 
        }
    }
    return ans
}

func findLessEqualThan (nums []int, target, left, right  int) int {
        for left < right {
            mid := left + (right - left + 1) / 2 
            if nums[mid] <= target {
                left = mid
            } else {
                right = mid - 1
            }
        }
        return right
}

func findGreaterEqualThan (nums []int, target, left, right  int) int {
        for left < right {
            mid := left + (right - left) / 2 
            if nums[mid] < target {
                left = mid + 1
            } else {
                right = mid 
            }
        }
        return right
}