千问 LeetCode 2040.两个有序数组的第 K 小乘积 public long kthSmallestProduct(int[] nums1, int[] nums2, long k)

张开发
2026/5/2 9:08:28 15 分钟阅读

分享文章

千问    LeetCode 2040.两个有序数组的第 K 小乘积 public long kthSmallestProduct(int[] nums1, int[] nums2, long k)
你提到的题目是 LeetCode 2040. 两个有序数组的第 K 小乘积。这是一个典型的 二分答案 分类讨论 的难题。 题目简述给定两个升序排列的整数数组 nums1 和 nums2以及一个整数 k要求返回所有可能乘积 nums1[i] * nums2[j] 中第 k 小的值从 1 开始计数。- 数组长度可达 5 times 10^4所以不能暴力枚举会超时。- 元素范围[-10^5, 10^5]乘积范围约为 [-10^{10}, 10^{10}]。✅ 解题思路二分答案 计数函数核心思想我们不去生成所有乘积而是猜一个答案 mid然后快速判断有多少个乘积 ≤ mid如果这个数量 ≥ k说明真实答案 ≤ mid否则 mid。于是可以二分搜索答案。 关键难点如何高效计算 count 满足 nums1[i] * nums2[j] k) {right mid; // 第 k 小 ≤ mid} else {left mid 1;}}return left;}// 计算有多少对 (i, j) 满足 nums1[i] * nums2[j] 0 ? nums2.length : 0;}long cnt 0;int n nums2.length;if (x 0) {// x 0: nums2 升序 → 乘积升序 → 找最大的 j 使得 x * nums2[j] -5需向下取整limit--;}// 找最后一个小于等于 limit 的位置upper_bound - 1int lo 0, hi n;while (lo ceil(target / x) 注意除法向零取整需调整long limit target / x;if (target % x ! 0 (target 0) (x 0)) {// 同号且有余数 → 需要向上取整但 Java 除法向零取整limit;}// 找第一个 limit 的位置int lo 0, hi n;while (lo limit) {hi mid;} else {lo mid 1;}}cnt n - lo; // [lo, n) 满足}return cnt;}⚠️ 注意事项易错点1. 整数除法截断问题Java 中 -5 / 2 -2向零取整但我们需要向下取整floor division来保证不等式正确。- 例如x3, target-5 → limit floor(-5/3) -2- 可通过检查余数符号来修正。2. 二分边界通常用 [left, right) 或 [left, right]保持一致即可。上面代码用的是 [left, right)。3. 溢出虽然 x 和 nums2[j] 是 int但乘积可能达 1e10所以用 long 存储中间结果。 替代思路更简洁但稍慢也可以不对除法做精细修正直接在 countForX 中对 nums2 进行二分每次计算 x * nums2[mid] 并与 target 比较避免除法private long countForX(int[] nums2, long x, long target) {int n nums2.length;int left 0, right n - 1;int pos -1;if (x 0) {// 乘积非递减while (left right) {int mid (left right) / 2;if (x * nums2[mid] target) {pos mid;left mid 1;} else {right mid - 1;}}return pos 1;} else {// 乘积非递增while (left right) {int mid (left right) / 2;if (x * nums2[mid] target) {pos mid;right mid - 1;} else {left mid 1;}}return pos -1 ? 0 : n - pos;}}这种写法逻辑更直观且避免了除法陷阱推荐使用✅ 总结- 方法二分答案 对每个 x ∈ nums1 在 nums2 中二分计数。- 时间复杂度O(n log m cdot log W)其中 W 2 times 10^{10}。- 关键处理 x 正负时乘积序列单调性不同二分方向要变。如果你希望我提供 C / Python 版本或者解释某个细节比如除法修正随时告诉我

更多文章