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

LeetCode 982题解:位运算优化三元组计数问题

1. 问题背景与核心挑战

今天遇到一道有趣的LeetCode题目(编号982),要求统计数组中满足特定条件的三元组数量。题目描述很简单:给定一个整数数组nums,返回满足nums[i] & nums[j] & nums[k] == 0的三元组(i, j, k)的数量,其中0 ≤ i, j, k < nums.length。

这个按位与操作的三元组问题看似直接,实则暗藏玄机。当我第一次看到这个题目时,脑海中立即浮现出几个关键疑问:

  1. 暴力解法的时间复杂度是多少?在数据量较大时是否可行?
  2. 按位与运算有哪些特性可以利用来优化?
  3. 是否存在某种数学规律或位运算技巧可以降低计算复杂度?

经过一番探索,我发现这个问题完美展示了位运算与算法优化的精妙结合。下面分享我的解题思路和最终实现的优化方案。

2. 暴力解法分析与复杂度评估

最直观的解法当然是三重循环暴力枚举:

public int countTriplets(int[] nums) { int count = 0; int n = nums.length; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { if ((nums[i] & nums[j] & nums[k]) == 0) { count++; } } } } return count; }

这个解法的时间复杂度是O(n³),当n=1000时,循环次数将达到10亿次,显然无法在合理时间内完成。在LeetCode上测试时,这个解法会直接超时。

提示:在实际面试中,即使你能想到优化方案,也应该先提出暴力解法并分析其复杂度,这展示了你的系统性思维。

3. 位运算特性与优化思路

3.1 按位与运算的基本性质

按位与(&)运算有几个重要特性:

  1. 任何数与0进行按位与运算结果都是0
  2. 按位与具有结合律:(a & b) & c = a & (b & c)
  3. 按位与的结果不会大于任一操作数

这些性质提示我们可以利用中间结果进行优化,避免重复计算。

3.2 关键优化思路:预计算两数组合

观察到三元组的按位与可以拆分为两步:

  1. 先计算nums[i] & nums[j]的所有可能结果
  2. 然后检查这些结果与nums[k]的按位与是否为0

这样我们可以将O(n³)的问题转化为O(n²) + O(n²)的问题。具体步骤:

  1. 预计算所有nums[i] & nums[j]的结果,存储它们的频率
  2. 对于每个预计算结果和每个nums[k],检查它们的按位与是否为0
  3. 根据频率统计有效三元组数量

4. 优化实现与代码解析

基于上述思路,下面是优化后的Java实现:

public int countTriplets(int[] nums) { int maxNum = 1 << 16; // 题目中nums[i] < 2^16 int[] freq = new int[maxNum]; int n = nums.length; // 预计算所有nums[i] & nums[j]的频率 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { freq[nums[i] & nums[j]]++; } } int count = 0; // 检查每个预计算结果与nums[k]的按位与 for (int k = 0; k < n; k++) { for (int m = 0; m < maxNum; m++) { if ((m & nums[k]) == 0) { count += freq[m]; } } } return count; }

4.1 复杂度分析

  • 空间复杂度:O(2¹⁶),用于存储频率数组
  • 时间复杂度:O(n² + n*2¹⁶)
    • 预计算阶段:O(n²)
    • 统计阶段:O(n*2¹⁶)

虽然理论复杂度仍然较高,但在实际测试中这个解法能够通过LeetCode的所有测试用例,因为2¹⁶=65536是一个固定常数。

5. 进一步优化:位掩码技巧

我们可以利用位运算的性质进一步优化内层循环:

public int countTriplets(int[] nums) { int maxNum = 1 << 16; int[] freq = new int[maxNum]; int n = nums.length; for (int num : nums) { for (int num2 : nums) { freq[num & num2]++; } } int count = 0; for (int num : nums) { int mask = num ^ 0xFFFF; // 取反操作 int subset = mask; do { count += freq[subset]; subset = (subset - 1) & mask; } while (subset != mask); } return count; }

这个优化利用了位掩码的枚举技巧,将内层循环从遍历所有可能的m改为只遍历与nums[k]按位与为0的那些m。这种方法在最坏情况下复杂度相同,但在实际运行中通常更快。

6. 边界条件与测试用例

在实现这类位运算问题时,特别需要注意边界条件:

  1. 空数组输入:应该返回0
  2. 单个元素数组:如果元素为0,返回1(0&0&0=0);否则返回0
  3. 全0数组:任何三元组都满足条件,返回n³
  4. 全1数组:只有所有元素按位与才为1,不满足条件,返回0

测试用例示例:

@Test public void testCountTriplets() { Solution solution = new Solution(); assertEquals(12, solution.countTriplets(new int[]{2, 1, 3})); assertEquals(27, solution.countTriplets(new int[]{0, 0, 0})); assertEquals(0, solution.countTriplets(new int[]{1, 1, 1})); assertEquals(1, solution.countTriplets(new int[]{0})); assertEquals(0, solution.countTriplets(new int[]{1})); }

7. 同类问题与扩展思考

这类按位运算的组合计数问题在编程竞赛中很常见。类似的问题包括:

  1. 按位或为零的三元组计数
  2. 按位异或为特定值的三元组计数
  3. 子数组按位与/或/异或的统计

解决这类问题的通用思路是:

  1. 分析位运算的性质
  2. 寻找可以预计算的中间结果
  3. 利用位掩码技巧优化枚举过程
  4. 考虑分治或按位处理的策略

对于更大的数据规模(如n=10⁵),可能需要更高级的数据结构或数学方法,如快速沃尔什变换(FWT)等。

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

相关文章:

  • 从向量点积到Transformer:揭秘大语言模型如何生成下一个词
  • 攻克音频功放交越失真:从原理分析到甲乙类偏置电路实战调试
  • 深入SIMD向量搜索内核:从算法原理到AVX2/NEON硬件级优化实践
  • C++策略模式实战:游戏开发中的行为动态切换
  • 软件工程核心三图:类图、时序图、活动图实战指南
  • 2026年8月玻璃钢景观雕塑/惠州玻璃钢真空导流壳体厂家推荐测评_惠州市驰顺实业有限公司 - 品牌宣传支持者
  • 深度解读|LLM Wiki 的工程实践,从 AI Coding、Obsidian 到 RAG 协同。
  • VSCode插件生态:从AI编程到代码质量,打造高效开发环境
  • 从本地到云端:OpenClaw应用迁移实战与避坑指南
  • 风力叶片缺陷数据集 风力发电机组件语义分割数据集 检测分割风力发电叶片的分割
  • AiZynthFinder:快速高效的逆合成规划终极指南 [特殊字符]
  • 猫抓浏览器扩展架构设计与网页资源嗅探技术深度解析
  • Linux内核efifb驱动:UEFI启动图形显示的基石与实战
  • 从零到国一:成图大赛备赛实战框架与工程思维养成
  • 企业系统整合实战:绕过标准API实现泛微OA与用友U8数据同步
  • 从零构建多品类牌类AI决策API:架构设计与性能优化实战
  • Harness Engineering:模型驱动的线束系统工程实践与工具链解析
  • Git命令速查手册:从基础配置到高级技巧
  • VSCode插件生态全解析:从智能编码到全栈开发的高效实践
  • 从零跑通一套 AI Agent 自动复盘工作流
  • 2026年8月深圳金属镂空骰子/金属镂空骰子厂家口碑推荐_深圳市铭丰工艺制品有限公司 - 行业平台推荐
  • 技术人如何明确需求:从模糊想法到技术规格的四步拆解法
  • 深入解析插入损耗:原理、测量与布线故障排查实战指南
  • 出差整理客户访谈录音,2026可以语音转文字的app哪个好攻略
  • 2026 年聊城有实力的美麟鸡柳棒品牌选哪家,吃了十年的鸡柳棒,居然藏着这样的门道?-立信食品 - 行业推荐官-2
  • 2026年程序员职业突破指南:利用大模型实现薪资十倍增长,揭秘2025年技术变革下的职业转型与价值升级策略!
  • 算法面试高频题精讲:从链表、二叉树到动态规划与滑动窗口
  • 从四足到人形:机器人技术栈的跃迁与核心挑战解析
  • 2026年8月菏泽百度AI推广/百度AI推广服务公司哪家好_菏泽云起信息技术有限公司 - 行业平台推荐
  • 洛本文艺评论的概况