news 2026/5/2 9:08:27

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
千问 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 - 1)
int 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)来保证不等式正确。
- 例如:x=3, 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 版本,或者解释某个细节(比如除法修正),随时告诉我!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 9:08:26

3步掌握NHSE:动物森友会存档编辑器的深度应用指南

3步掌握NHSE&#xff1a;动物森友会存档编辑器的深度应用指南 【免费下载链接】NHSE Animal Crossing: New Horizons save editor 项目地址: https://gitcode.com/gh_mirrors/nh/NHSE NHSE&#xff08;New Horizons Save Editor&#xff09;是一款专为《集合啦&#xff…

作者头像 李华
网站建设 2026/5/2 9:02:57

Kai 9000:构建具备持久记忆与跨平台执行能力的开源AI助手

1. 项目概述&#xff1a;一个全平台、开源的智能体新范式 如果你和我一样&#xff0c;对市面上那些“健忘”的AI助手感到厌倦&#xff0c;每次对话都像在和一个失忆症患者重新认识&#xff0c;那么你可能会对Kai 9000产生兴趣。这不是又一个套壳的ChatGPT前端&#xff0c;而是一…

作者头像 李华
网站建设 2026/5/2 9:02:06

如何高效使用MTKClient:联发科设备底层调试终极解决方案

如何高效使用MTKClient&#xff1a;联发科设备底层调试终极解决方案 【免费下载链接】mtkclient MTK reverse engineering and flash tool 项目地址: https://gitcode.com/gh_mirrors/mt/mtkclient MTKClient是一款专业的联发科芯片调试工具&#xff0c;支持从MT6261到M…

作者头像 李华
网站建设 2026/5/2 9:00:14

如何高效突破百度网盘限速:终极开源解析工具实战指南

如何高效突破百度网盘限速&#xff1a;终极开源解析工具实战指南 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 百度网盘作为国内主流的云存储服务&#xff0c;其免费用户的下…

作者头像 李华
网站建设 2026/5/2 8:52:55

机器人视觉运动策略泛化:对象中心表示与Slot Attention机制

1. 机器人视觉运动策略泛化的关键挑战 在机器人视觉运动控制领域&#xff0c;如何让策略具备强大的泛化能力一直是核心难题。想象一下&#xff0c;当你教机器人抓取杯子时&#xff0c;希望它不仅能识别训练时见过的蓝色马克杯&#xff0c;还要能应对厨房里突然出现的红色玻璃杯…

作者头像 李华
网站建设 2026/5/2 8:51:19

AI驱动的SEO与GEO优化智能体:自动化网站搜索排名提升实战

1. 项目概述&#xff1a;一个面向AI编程工具的终极SEO与GEO优化智能体如果你是一名开发者、营销人员或创始人&#xff0c;正在使用Claude Code、Cursor、GitHub Copilot这类AI编程助手来构建或维护网站&#xff0c;那么你很可能面临一个共同的痛点&#xff1a;如何高效地、系统…

作者头像 李华