LeetCode-Go 题解:2183. Count Array Pairs Divisible by K(GCD 因子统计 + 组合计数)
LeetCode-Go 题解2183. Count Array Pairs Divisible by KGCD 因子统计 组合计数【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go本文基于 LeetCode-Go 仓库中 2183 题解目录 的解题思路与 Go 实现深入拆解“统计乘积能被 k 整除的下标对”这一经典数论计数问题。你将掌握如何用最大公约数GCD把大规模数组降维成 k 的因子频次表再通过 O(√k) 级别的因子遍历与组合数学完成计数并理解仓库源码中每一行代码的推导依据最终能够独立写出可应对 10^5 级数据量的高效解法。问题定义与约束题目要求见 README 原文给定一个下标从 0 开始、长度为n的整数数组nums和一个整数k返回满足以下两个条件的下标对(i, j)的数目0 i j n - 1nums[i] * nums[j]能被k整除关键约束1 nums.length 10^51 nums[i], k 10^5示例 1Input: nums [1,2,3,4,5], k 2 Output: 7满足乘积能被 2 整除的 7 个下标对为(0,1), (0,3), (1,2), (1,3), (1,4), (2,3), (3,4)对应乘积分别为 2、4、6、8、10、12、20。示例 2Input: nums [1,2,3,4], k 5 Output: 0n最大可达 10^5最坏情况下下标对数量约为 5×10^9 量级因此返回值类型必须使用 64 位整数Go 中为int64同时也决定了不能枚举所有下标对必须寻找数论层面的优化。核心思路用 GCD 把数组降维成因子频次表暴力做法是枚举所有(i, j)并逐一判断nums[i] * nums[j] % k 0时间复杂度 O(n²)在n 10^5时完全不可行。仓库题解给出了一个精妙的降维思路见 README 解题思路先算每个元素与 k 的最大公约数对于每个nums[i]计算g gcd(nums[i], k)。统计这些 gcd 的频次把所有g存入 mapgcds[g]。在因子空间上做两两配对只有gcd(nums[i], k) * gcd(nums[j], k)能被k整除时nums[i] * nums[j]才一定且仅当能被k整除此时(i, j)才是一对合法下标对。为什么可以这样替换设a nums[i]b nums[j]。若a * b % k 0则对任意整数xgcd(x, k)恰好保留了x中与k相关的全部质因子。因此a * b能被k整除当且仅当gcd(a, k) * gcd(b, k)能被k整除。这个等价关系把问题从“原始数值”空间转移到“k 的因子”空间。因子个数的 O(√k) 上界证明题解特别强调循环只需算到 O(√k)因为每个gcd(nums[i], k)一定是k的因子而k的因子总数不超过 O(√k)。简单证明如下假设v是k的一个因子那么k/v也必然是k的因子。v与k/v中必至少有一个小于等于 √k。把每一对互补因子(v, k/v)看成一组k 的全部因子最多可被划分为不超过 √k 组所以因子总数不超过2 * √k O(√k)个。这意味着 map 的 key 集合规模至多为 O(√k)k 10^5时最多几百个即使在其上做两层循环代价也完全可以接受。算法步骤详解整体流程可以划分为三个阶段第一步统计 gcd 频次遍历数组对每个元素计算它与k的最大公约数并计数。仓库源码中直接以int(math.Sqrt(float64(k)))作为 map 的初始容量正好利用了“因子数量不超过 O(√k)”这一结论做容量预分配避免 map 频繁扩容。第二步在因子空间上双层遍历配对枚举 map 中所有 key 对(a, b)若a b直接跳过。这是去重手段保证每个无序下标对只被统计一次只统计一次即可覆盖所有组合因为 map 遍历是无序的必须人为约定遍历顺序。若(a * b) % k ! 0说明这两个 gcd 因子相乘无法被k整除跳过。否则进入第三步进行计数。第三步组合数学计数若a ! b凡是 gcd 等于a的任意元素与 gcd 等于b的任意元素配对都合法下标对数量为n1 * n2n1、n2分别为两个 gcd 的频次。若a b同一 gcd 组内配对相当于从n1个元素中任选 2 个数量为组合数C(n1, 2) n1 * (n1 - 1) / 2。最后把所有计数累加即为答案。仓库源码逐行解析以下是仓库中 2183. Count Array Pairs Divisible by K.go 的完整实现package leetcode import math func countPairs(nums []int, k int) int64 { n : int(math.Sqrt(float64(k))) gcds, res : make(map[int]int, n), 0 for _, num : range nums { gcds[gcd(num, k)] } for a, n1 : range gcds { for b, n2 : range gcds { if a b || (a*b)%k ! 0 { continue } if a ! b { res n1 * n2 } else { // a b res n1 * (n1 - 1) / 2 } } } return int64(res) } func gcd(a, b int) int { for a%b ! 0 { a, b b, a%b } return b }关键点逐一说明make(map[int]int, n)n为√k向下取整用“因子数不超过 2√k”的结论预估容量减少扩容。gcds[gcd(num, k)]单次遍历即完成频次统计时间复杂度 O(n·log k)。双层for a, n1 : range gcds遍历key 集合大小至多 O(√k)内层同样如此所以配对阶段复杂度为 O(√k × √k) O(k)而由于 map 中实际存在的 key 数通常远小于 2√k实际开销更低。if a b || (a*b)%k ! 0 { continue }一行同时完成去重与整除性过滤。a ! b分支与a b分支分别对应“跨组配对”的n1 * n2与“组内配对”的组合数C(n1, 2)是本题计数的核心与 README 代码段 完全一致。最终return int64(res)因为结果可能超过int在 32 位平台上的表示范围最坏约 5×10^9必须显式转为int64。gcd采用欧几里得算法辗转相除法实现当a % b ! 0时不断互换最终返回最大公约数b。复杂度分析时间复杂度统计阶段 O(n·log k)gcd 计算配对阶段 O(T²)其中 T 为 k 的因子数量T ≤ 2√k因此总体为 O(n·log k k)在给定约束n, k 10^5下表现优秀。空间复杂度O(√k)用于存放 gcd 频次 map。测试用例验证仓库配套的 2183. Count Array Pairs Divisible by K_test.go 完整覆盖了题目给出的两个示例countPairs([]int{1, 2, 3, 4, 5}, 2)期望输出7countPairs([]int{1, 2, 3, 4}, 5)期望输出0。测试代码通过结构体question2182组织参数与期望答案在Test_Problem2182中依次打印输入与输出。以示例 1 为例可手工验证算法正确性nums各元素与k2的 gcd 分别为1, 2, 1, 2, 1频次表为{1: 3, 2: 2}因子对(1, 2)乘积为 2 能被 2 整除贡献3 × 2 6因子对(2, 2)组内配对贡献C(2, 2) 1合计6 1 7与期望一致。在仓库根目录go.mod 声明了module github.com/halfrost/LeetCode-GoGo 版本 1.19执行go test即可运行该目录下所有用例go test ./leetcode/2183.Count-Array-Pairs-Divisible-by-K/ -v总结与举一反三本题是“gcd 降维 因子频次 组合计数”的典型代表解题的关键链条可以提炼为将“乘积可整除”的判定等价转化为“gcd 乘积可整除”把问题从原始数值空间投影到 k 的因子空间利用 k 的因子个数不超过 O(√k) 的性质把看似 O(n²) 的配对问题压缩到 O(k) 的因子对遍历使用组合数学分别处理跨组配对n1 × n2与组内配对C(n1, 2)并用a b保证每个无序对只计一次。这一思路同样适用于其他“乘积/和能被某数整除”的计数问题凡是需要统计满足整除性质的二元组都可以优先考虑先求每个元素与 k 的 gcd或取模再利用因子空间的有限性做计数从而避开 O(n²) 的暴力枚举。若读者希望深入该仓库的其他数论与计数类题解可继续浏览 leetcode 目录下对应的题目讲解。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

伺服编码器停产替代的三条实战路径

伺服编码器停产替代的三条实战路径

1. 这不是换零件,是给产线做一次“神经外科手术”上周五下午三点,我接到华东一家汽车零部件厂的紧急电话。他们产线上那台用了八年的德国伺服压装机突然报错——编码器信号丢失。维修师傅拆开一看,原装的Heidenhain ECN 1313-2048已经停产三年…

2026/9/13 19:23:01 阅读更多 →
Effect v4 CLI 全局设置标志直接可 yield:解读 `GlobalFlag.setting` 与内置标志重命名

Effect v4 CLI 全局设置标志直接可 yield:解读 `GlobalFlag.setting` 与内置标志重命名

Effect v4 CLI 全局设置标志直接可 yield:解读 GlobalFlag.setting 与内置标志重命名 【免费下载链接】t3code 项目地址: https://gitcode.com/GitHub_Trending/t3/t3code 导读 在 Effect v4(当前处于 RC 阶段,main 分支即 v4 开发分…

2026/9/13 19:23:01 阅读更多 →
Triton GSan 全局内存并发消毒器:向量时钟、影子内存与分布式竞态检测的设计与实现

Triton GSan 全局内存并发消毒器:向量时钟、影子内存与分布式竞态检测的设计与实现

Triton GSan 全局内存并发消毒器:向量时钟、影子内存与分布式竞态检测的设计与实现 【免费下载链接】triton Development repository for the Triton language and compiler 项目地址: https://gitcode.com/GitHub_Trending/tri/triton GSan(Glob…

2026/9/13 19:23:01 阅读更多 →

最新新闻

李飞飞十年前论文获时间检验奖

李飞飞十年前论文获时间检验奖

AI科技圈最近一周又发生了啥新鲜事? 25位菲尔兹奖得主联合发表公开信 陶哲轩、邓煜等25位菲尔兹奖得主联合署名发表公开信《人工智能在数学中的严重错位》,指出AI公司把解决数学问题当作基准测试来推进的做法,与数学共同体追求概念性理解与洞…

2026/9/14 21:53:18 阅读更多 →
用OpenSpec与Superpowers构建AI辅助的SDD+TDD开发工作流

用OpenSpec与Superpowers构建AI辅助的SDD+TDD开发工作流

1. 为什么我最终选择用 OpenSpec Superpowers 搭 SDDTDD 工作流过去大半年,我一直在折腾怎么让 AI 助手更听话、更可靠地帮我写代码。最早的时候,我和大部分人一样,直接在对话框里描述需求,AI 生成代码,我 review、修…

2026/9/14 21:53:18 阅读更多 →
[论文学习]Claude Code 沙箱机制:文件系统与网络隔离在智能体编程中的工程实践

[论文学习]Claude Code 沙箱机制:文件系统与网络隔离在智能体编程中的工程实践

Claude Code Sandboxing: Filesystem Network Isolation for Agentic Coding 论文重点 Anthropic 工程团队为 Claude Code 引入了一套基于操作系统原生能力的沙箱隔离机制,通过文件系统隔离与网络隔离的双边界设计,让 AI 编程智能体在预定义的安全边界内…

2026/9/14 21:53:18 阅读更多 →
AI生成测试用例实战:从输入工程化到Harness工程化

AI生成测试用例实战:从输入工程化到Harness工程化

做了这么多年测试,我越来越觉得,写测试用例这件事最耗精力的不是“设计”,而是把脑子里的判断翻译成一行行看得见、能执行、不重不漏的表格。尤其是功能测试用例,字段一多、分支一多,光是把等价类和边界值铺开就能铺一…

2026/9/14 21:53:18 阅读更多 →
康复治疗学毕业论文怎么写?量表、功能评定和干预效果怎么避免写成训练记录

康复治疗学毕业论文怎么写?量表、功能评定和干预效果怎么避免写成训练记录

康复治疗学毕业论文怎么写?量表、功能评定和干预效果怎么避免写成训练记录 康复治疗学论文很容易写成“做了哪些训练”的实践记录。治疗项目写得很详细,患者每周做几次也写得很清楚,但真正的功能变化、评价量表和研究结论没有形成闭环。到了论…

2026/9/14 21:53:18 阅读更多 →
OpenClaw 跑本地智能体任务:Key 用 TaoToken

OpenClaw 跑本地智能体任务:Key 用 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 21:52:17 阅读更多 →

日新闻

AI音乐侵权案中的测试工程与版权保护技术

AI音乐侵权案中的测试工程与版权保护技术

1. 项目概述:当测试工程师遇上AI音乐侵权案去年夏天,我作为技术顾问参与了一起特殊的著作权纠纷案——某音乐平台AI作曲功能被指控批量侵权。这起案件的特殊性在于:原告方并非传统音乐人,而是一家拥有百万级曲库的数字音乐发行商&…

2026/9/14 0:00:26 阅读更多 →
嵌入式面试I2C与SPI深度解析:从协议到量产调试

嵌入式面试I2C与SPI深度解析:从协议到量产调试

1. 这份“高频知识点洞察”到底是什么,又为什么值得你花时间细读? 如果你最近在刷嵌入式开发岗位的招聘JD,或者正坐在工位上改第7版简历,又或者刚被面试官一句“讲讲I2C和SPI的区别”问得手心冒汗——那你不是一个人。过去两年我带…

2026/9/14 0:00:26 阅读更多 →
51单片机开环控制磁阻传感器的硬件匹配与代码实现

51单片机开环控制磁阻传感器的硬件匹配与代码实现

简介:本资源是一份面向嵌入式初学者与单片机课程实践者的51单片机开关磁阻电机(SRM)开环控制教学方案,聚焦磁阻位置检测、固定时序驱动与基础状态可视化。资源包含1个C语言主程序文件(zhuang600.c)实现电机…

2026/9/14 0:00:26 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/14 5:45:49 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/14 0:52:26 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/14 0:06:41 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/14 17:35:10 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/14 16:59:29 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/14 5:45:14 阅读更多 →