当前位置: 首页 > news >正文

LeetCode每日一题4.19

2563. 统计公平数对的数目

题目

在这里插入图片描述

问题分析

输入:一个整数数组 nums 和两个整数 lower 和 upper。
输出:返回满足条件的公平数对的数目,即对于所有 0 <= i < j < n,lower <= nums[i] + nums[j] <= upper 的数对 (i, j) 的数量。

思路

方法一:暴力解法(时间复杂度 O(n^2))
直接遍历所有可能的数对 (i, j) 并检查它们是否满足条件。
方法二:优化解法(二分查找)
排序:首先对数组 nums 进行排序。
遍历:然后对每个 nums[i],使用 二分查找 来找到满足条件的 nums[j](其中 j > i)的范围。
二分查找:分别找到满足 nums[i] + nums[j] <= upper 的最大 j(通过 find_upper_bound)和满足 nums[i] + nums[j] >= lower 的最小 j(通过 find_lower_bound)。

代码

class Solution:def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:# 对数组进行排序nums.sort()count = 0n = len(nums)for i in range(n):# 找到满足 nums[i] + nums[j] <= upper 的最大 j 的位置r = self.find_upper_bound(nums, upper - nums[i], i + 1, n - 1)# 找到满足 nums[i] + nums[j] >= lower 的最小 j 的位置l = self.find_lower_bound(nums, lower - nums[i], i + 1, n - 1)# 统计符合条件的数对数量if l <= r:count += r - l + 1return countdef find_upper_bound(self, nums, target, start, end):while start <= end:mid = (start + end) // 2if nums[mid] > target:end = mid - 1else:start = mid + 1return enddef find_lower_bound(self, nums, target, start, end):while start <= end:mid = (start + end) // 2if nums[mid] < target:start = mid + 1else:end = mid - 1return start

复杂度分析

时间复杂度:
排序:(O(n \log n))
遍历并二分查找:(O(n \log n))
因此,最终时间复杂度为:
[ O(n \log n) + O(n \log n) = O(n \log n) ]
空间复杂度:
遍历:(O(n))

学习

排序

排序是为了后续能够利用 二分查找 来高效地找到满足条件的 nums[j]。

遍历

for i in range(n):r = self.find_upper_bound(nums, upper - nums[i], i + 1, n - 1)l = self.find_lower_bound(nums, lower - nums[i], i + 1, n - 1)if l <= r:count += r - l + 1

遍历每个 nums[i]:对于每个 nums[i],我们需要找到所有 j > i 且满足 lower <= nums[i] + nums[j] <= upper 的 nums[j]。
找到 r 和 l:
r 是满足 nums[i] + nums[j] <= upper 的最大 j 的位置。
l 是满足 nums[i] + nums[j] >= lower 的最小 j 的位置。
统计数对:如果 l <= r,则 l 到 r 之间的所有 j 都是符合条件的,因此数对数量为 r - l + 1。

二分查找

find_upper_bound:找到第一个大于 target 的元素的位置(返回该位置的前一个位置)。

  def find_upper_bound(self, nums, target, start, end):while start <= end:mid = (start + end) // 2if nums[mid] > target:end = mid - 1else:start = mid + 1return end

find_lower_bound:找到第一个不小于 target 的元素的位置。

  def find_lower_bound(self, nums, target, start, end):while start <= end:mid = (start + end) // 2if nums[mid] < target:start = mid + 1else:end = mid - 1return start

与相向双指针方法的区别

相向双指针方法 的典型特点是:
两个指针从两端向中间移动:一个指针从数组的起始位置开始(left),另一个指针从数组的末尾位置开始(right)。
根据当前 nums[left] + nums[right] 的值来决定移动哪个指针:
如果当前和小于 lower,则 left 指针右移。
如果当前和大于 upper,则 right 指针左移。
如果当前和在 [lower, upper] 范围内,则统计符合条件的数对并调整指针。

http://www.xdnf.cn/news/28603.html

相关文章:

  • 【Bluedroid】蓝牙存储模块配置管理:启动、读写、加密与保存流程解析
  • sqlilabs-Less之HTTP头部参数的注入——基础篇
  • [HCIP] OSPF 综合实验
  • Vue3+TS中svg图标的使用
  • 数据分析与挖掘
  • RAGFlow在Docker中运行Ollama直接运行于主机的基础URL的地址
  • opencv 给图片和视频添加水印
  • leetcode57.插入区间
  • Windows系统C盘深度清理指南
  • 车载诊断新架构--- SOVD初入门(上)
  • 23种设计模式-创建型模式之原型模式(Java版本)
  • 医疗器械电磁兼容相关标准
  • 豆瓣图书数据采集与可视化分析(一)- 豆瓣图书数据爬取
  • 性能比拼: Deno vs. Node.js vs. Bun (2025版)
  • C++之虚函数 Virtual Function
  • Redis 的持久化机制(RDB, AOF)对微服务的数据一致性和恢复性有何影响?如何选择?
  • 零基础上手Python数据分析 (18):Matplotlib 基础绘图 - 让数据“开口说话”
  • FPGA——基于DE2_115实现DDS信号发生器
  • FPGA IO引脚 K7-认知4
  • 【java实现+4种变体完整例子】排序算法中【插入排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
  • windows下用xmake交叉编译鸿蒙.so库
  • 交换机与路由器的主要区别:深入分析其工作原理与应用场景
  • hackmyvm-airbind
  • 【人工智能学习-01-01】20250419《数字图像处理》复习材料的word合并PDF,添加页码
  • AI 趋势下 Python 的崛起:深度剖析
  • Nginx 报错403 排查与解决
  • Oracle Recovery Tools修复ORA-600 6101/kdxlin:psno out of range故障
  • CSS中的`transform-style`属性:3D变换的秘密武器
  • 【每日八股】复习计算机网络 Day2:TCP 断开连接时四次挥手及其相关问题
  • 关于大型语言模型的“生物学”