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

LeetCode 3740:三个相等元素间的最小距离超详细题解

LeetCode 3740:三个相等元素间的最小距离超详细题解

LeetCode 3740. 三个相等元素之间的最小距离 1【暴力枚举+数学优化+哈希表优化】超详细题解

题目描述

给你一个整数数组nums

如果满足nums[i] == nums[j] == nums[k],且(i, j, k)3 个不同下标,那么三元组(i, j, k)被称为有效三元组

有效三元组的距离被定义为abs(i - j) + abs(j - k) + abs(k - i)

返回有效三元组的最小可能距离。如果不存在有效三元组,返回-1

解题思路

1. 数学公式化简(核心优化)

首先对距离公式进行化简,这是本题最关键的一步:

设三个下标满足a < b < c

距离公式:

∣a−b∣+∣b−c∣+∣c−a∣|a-b| + |b-c| + |c-a|ab+bc+ca

化简后:

(b−a)+(c−b)+(c−a)=2∗(c−a)(b-a) + (c-b) + (c-a) = 2*(c - a)(ba)+(cb)+(ca)=2(ca)

结论:三个数的距离 =2 × (最大下标 - 最小下标)

中间下标不影响结果!这一结论对所有优化思路均适用。

2. 算法思路(两种实现)

方法一:暴力枚举(O(n³),适合小数据量)
  1. 三重循环枚举:遍历所有i < j < k的组合,确保三个下标互不相同;

  2. 判断有效性:检查nums[i] == nums[j] == nums[k],确认是有效三元组;

  3. 计算距离:使用化简公式2*(k-i),避免冗余计算;

  4. 记录最小值:遍历完成后返回最小距离,若无有效三元组则返回-1

方法二:哈希表优化(O(n²),适合更大数据量)

核心思路:利用哈希表分组,减少无效枚举,将时间复杂度从 O(n³) 降至 O(n²)。

  1. 分组存储:用哈希表(字典)记录每个数字对应的所有下标,key 为数组元素值,value 为该元素出现的所有下标组成的列表;

  2. 筛选有效分组:仅保留下标列表长度 ≥3 的分组(只有这类分组才可能存在有效三元组);

  3. 两两枚举求最小距离:对每个有效分组,遍历所有下标对(a, c)(确保a < c),由于中间下标 b 必然存在(列表长度 ≥3),直接用公式2*(c - a)计算距离,记录该分组的最小距离;

  4. 全局求最小:汇总所有有效分组的最小距离,取全局最小值,无有效分组则返回-1

优化原理:同一数字的下标集中存储,避免遍历无关数字的组合,减少大量无效循环(例如数字 1 对应下标 [0,2,3],仅需遍历 (0,2)、(0,3)、(2,3) 三对,无需参与其他数字的枚举)。

3. 复杂度分析(两种方法对比)

算法方法时间复杂度空间复杂度适用场景
暴力枚举O(n3)O(n^3)O(n3)O(1)O(1)O(1)n≤100n \le 100n100,小数据量、面试手写快速实现
哈希表优化O(n2)O(n^2)O(n2)O(n)O(n)O(n)n≥100n \ge 100n100,大数据量、追求更高效率
说明:本题提示中n≤100n \le 100n100,两种方法均能轻松通过;但当n≥1000n \ge 1000n1000时,O(n³) 会超时,此时哈希表优化版本的优势凸显。

AC 代码(两种版本)

版本一:暴力枚举版本(O(n³))

from typing import List class Solution: def minimumDistance(self, nums: List[int]) -> int: n = len(nums) min_dist = float('inf') # 枚举所有 i < j < k 的组合,确保下标互不相同 for i in range(n): for j in range(i + 1, n): for k in range(j + 1, n): # 判断是否为有效三元组(三个数字相等) if nums[i] == nums[j] == nums[k]: # 利用化简公式计算距离,无需复杂绝对值运算 current = 2 * (k - i) if current < min_dist: min_dist = current # 若未找到有效三元组,返回 -1,否则返回最小距离 return min_dist if min_dist != float('inf') else -1

版本二:哈希表优化版本(O(n²))

from typing import List from collections import defaultdict class Solution: def minimumDistance(self, nums: List[int]) -> int: # 哈希表:key = 数组元素,value = 该元素出现的所有下标列表 num_indices = defaultdict(list) n = len(nums) min_dist = float('inf') # 1. 遍历数组,填充哈希表,分组存储下标 for idx, num in enumerate(nums): num_indices[num].append(idx) # 2. 遍历每个有效分组(下标列表长度 ≥3) for num, indices in num_indices.items(): m = len(indices) if m < 3: continue # 不足3个下标,无法构成有效三元组,跳过 # 3. 两两枚举下标对 (a, c),a < c,计算距离 2*(c - a) # 优化:无需遍历所有两两组合,只要找到同组内最接近的两个下标(a,c),就能得到该组最小距离 for a in range(m): # 只需要遍历 a 后面的下标 c(a< c),避免重复计算 for c in range(a + 2, m): # c ≥ a+2,确保中间有下标 b,满足 a < b < c current = 2 * (indices[c] - indices[a]) if current < min_dist: min_dist = current # 4. 返回结果:无有效三元组则返回 -1 return min_dist if min_dist != float('inf') else -1

代码解释(分版本说明)

版本一:暴力枚举代码解释

  1. 初始化min_dist设为无穷大(float(‘inf’)),用于记录最小距离,初始值确保任何有效距离都能覆盖它;

  2. 三重循环:通过i range(n)j range(i+1, n)k range(j+1, n),严格保证i < j < k,避免下标重复;

  3. 有效判断:只有nums[i] == nums[j] == nums[k]时,才视为有效三元组,进行距离计算;

  4. 公式计算:直接使用化简后的2*(k-i),省略原始公式的绝对值运算,提升效率且避免计算错误;

  5. 结果返回:若min_dist仍为无穷大,说明无有效三元组,返回-1;否则返回记录的最小距离。

版本二:哈希表优化代码解释

  1. 哈希表初始化:使用defaultdict(list)构建哈希表,避免手动判断 key 是否存在,简化代码;

  2. 分组存储下标:遍历数组,将每个元素的下标存入对应 key 的列表中,实现“同值下标分组”;

  3. 筛选有效分组:仅处理下标列表长度 ≥3 的分组,直接跳过无法构成有效三元组的分组,减少无效运算;

  4. 两两枚举优化c range(a + 2, m)是关键优化——确保ac之间至少有一个下标b(满足a < b < c),避免无效的下标对;同时,同组内下标已排序,无需额外排序,直接计算距离;

  5. 全局最小距离:遍历所有有效分组,更新全局最小距离,最终返回结果,逻辑与暴力版本一致。

测试案例验证(两种版本均适用)

案例 1

输入:[1,2,1,1,3]

哈希表分组:{1: [0,2,3], 2: [1], 3: [4]},仅 1 的分组有效;

有效下标对:(0,2) → 2*(2-0)=4(无中间下标,跳过)、(0,3) → 2*(3-0)=6、(2,3) → 2*(3-2)=2(无中间下标,跳过);

最小距离为 6 ✅ 输出 6

案例 2

输入:[1,1,2,3,2,1,2]

哈希表分组:{1: [0,1,5], 2: [2,4,6], 3: [3]},1 和 2 的分组有效;

1 的分组有效下标对:(0,5) → 10、(1,5) → 8;2 的分组有效下标对:(2,6) → 8;

全局最小距离为 8 ✅ 输出 8

案例 3

输入:[1]

哈希表分组:{1: [0]},无有效分组;

输出 -1 ✅

总结

本题核心考点

  • 数学公式化简能力(核心!直接决定计算效率,避免冗余运算);

  • 枚举逻辑的边界处理(确保下标互不相同,有效三元组的判定);

  • 哈希表的应用(分组优化,降低时间复杂度,体现空间换时间的思想)。

补充说明:

  • 暴力版本适合面试手写,代码简洁、逻辑直观、不易出错,适配本题小数据量要求;

  • 哈希表优化版本适合大数据量场景,通过空间换时间,将时间复杂度从 O(n³) 降至 O(n²),体现算法优化思维;

  • 两种版本均基于“距离公式化简”的核心结论,可见数学推导在算法题中的重要性。

http://www.cnnetsun.cn/news/1805239.html

相关文章:

  • 新能源汽车,车载充电机仿真模型(基于PWM整流器)。输出功率3.3kw,前级PFC采用双闭环控制,电流畸变率小。后级采用移相全桥开环控制。 运行环境有matlab/simulink和plecs
  • m4s-converter:3分钟掌握B站缓存视频无损转换的终极解决方案
  • 终极AMD Ryzen调试工具:5步解锁CPU隐藏性能的完整指南
  • 本科生毕业论文通关秘籍:Paperxie 让你从选题到答辩一路开挂
  • 从浏览器输入 URL 到页面返回:一次互联网通信全过程
  • 高效构建:ALS-Community角色动画系统的专业解决方案
  • AiZynthFinder终极指南:如何用AI轻松规划复杂分子合成路线
  • 高效日志分析工具 glogg:跨平台日志查看器的专业指南
  • 腾讯混元涨价463%,国产大模型“白菜价“时代终结?
  • OpenClaw如何做好记忆持久化的 八、场景验证:三个 Mini Use Case 与用户反馈
  • 浏览器字体模糊怎么办?三步打造媲美Mac的清晰字体体验
  • 终极nvitop使用指南:10个技巧轻松监控GPU性能
  • 智慧学工系统怎么选才不踩坑 这些实际价值学校最该关注
  • Redis命令处理机制源码探究谱
  • 扩散模型不只是生成图片:手把手教你用DiffMIC搞定医学图像分类(附代码复现避坑指南)
  • Vite 驱动 Vue3 项目:从零到部署的完整实践
  • Unity内置语音关键词识别:打造轻量级离线语音交互方案
  • Salt Player开源项目深度解析:构建高性能Android本地音乐播放器的技术架构与实践
  • 小白友好:通义千问1.8B Docker部署避坑指南
  • Headless浏览器自动化:用DrissionPage搞定Cloudflare付费版5秒盾验证
  • 3分钟掌握m4s-converter:从B站缓存困境到MP4自由播放
  • 如何快速解锁加密音乐文件:Unlock Music的完整使用指南
  • 像素史诗·智识终端Web应用开发全栈指南:从后端API到前端交互
  • ChatterUI移动AI聊天应用终极指南:从本地部署到个性化定制完整教程
  • 【AI】open claw 梦境机制
  • VideoSrt:5分钟为视频自动生成字幕的免费开源神器
  • 如何将网页轻松转换为可编辑的Figma设计:5分钟完整指南
  • [Uni-app] 微信小程序圆环进度条实现与优化指南
  • 从零到一:在UniApp原生插件中集成并调用第三方硬件SDK
  • 如何彻底解决Cursor AI试用限制:免费解锁Pro功能的完整技术方案