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

千问 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 版本,或者解释某个细节(比如除法修正),随时告诉我!

http://www.jsqmd.com/news/737149/

相关文章:

  • 高效解锁Windows多用户远程桌面:RDPWrap完整实用指南
  • 从2010到2024:手把手教你用Python分析CUMCM历年赛题趋势(附数据与代码)
  • 告别PS!用HandyView这款免费看图神器,轻松搞定图像处理论文里的多图对比
  • 别再手动算排名了!用Python+TOPSIS法5分钟搞定多指标评价(附完整代码)
  • 京东e卡回收平台推荐:高价、安全、快速的三合一选择 - 团团收购物卡回收
  • SketchUp STL插件:5分钟实现3D设计到打印的无缝转换
  • 别再只学理论了!用H3C交换机实战802.1X:基于端口和基于MAC认证到底有啥区别?
  • TVA与CNN的历史性对决(3)
  • 华硕笔记本性能调校实战:3种高效方案解锁硬件潜能
  • 京东e卡回收平台靠谱吗?深度解析热门平台优缺点 - 团团收购物卡回收
  • 如何为Windows系统创建高性能虚拟显示器:ParsecVDisplay完整指南
  • 前端工程化:基于Node.js的图片资源自动化处理与资产管理实践
  • 别再死记公式了!用Python+MATLAB手把手带你玩转单自由度无阻尼振动(附代码)
  • GetQzonehistory终极指南:一键备份QQ空间十年回忆的完整方案
  • 如何用XXMI启动器轻松管理游戏模组:完整指南
  • Qt6.5在线安装保姆级教程:用国内镜像源告别龟速下载(附阿里云盘工具)
  • 3分钟快速上手:罗技鼠标宏绝地求生压枪脚本终极配置指南
  • Ubuntu 20.04下搞定gici-open编译:从glog报错到ceres版本冲突的保姆级排坑指南
  • 成对验证技术提升代码生成模型推理能力
  • TranslucentTB:3步打造Windows任务栏透明化,让你的桌面焕然一新
  • Kai 9000:构建具备持久记忆与跨平台执行能力的开源AI助手
  • LizzieYzy:围棋AI智能分析工具的完整指南,让你快速提升棋力
  • 保姆级教程:手把手教你修改PX4机型文件,让自定义无人机在QGC上完美显示
  • 如何快速解决RimSort中SteamCmd下载失败:3种实用权限配置方法
  • 从晶圆到焊球:保姆级图解WLCSP封装的八个关键步骤(附RDL与BOP选择指南)
  • Substrate跨链桥实战:从架构设计到安全部署
  • 别再只看ROC了!用‘价格斜率’构建ETF轮动策略,实测改善回撤(附Python代码)
  • 大语言模型长上下文处理能力评测框架LOCA-bench解析
  • 如何高效使用MTKClient:联发科设备底层调试终极解决方案
  • 解锁音乐自由:ncmdump如何帮你轻松转换网易云音乐NCM文件