3分钟解决数组去重难题:GitHub热门LeetCode解题库实战指南
你是否还在为数组去重问题浪费30分钟以上?是否遇到过空间复杂度超标的情况?本文将通过GitHub热门项目GitHub_Trending/le/LeetCode-Book中的经典题型,教你用两种高效策略解决数组重复元素查找问题,看完即可掌握时间复杂度O(N)、空间复杂度O(1)的最优解法。
问题定义与应用场景
在开发中,数组去重是数据处理的基础操作,例如:
- 用户ID列表去重
- 日志数据清洗
- 表单提交重复检测
本问题来源于剑指 Offer 03. 数组中重复的数字,要求在长度为n的数组nums中找出重复数字,数组元素取值范围为0~n-1。
方法一:哈希表追踪法
算法原理
利用哈希表(Hash Set)的O(1)查找特性,遍历数组过程中记录已出现元素,遇到重复立即返回。
实现步骤
- 初始化空集合
dic - 遍历数组每个元素:
- 若元素已在集合中,返回该元素
- 否则将元素加入集合
- 遍历结束未找到时返回-1(本题保证有重复元素)
代码实现
class Solution:
def findRepeatNumber(self, nums: [int]) -> int:
dic = set()
for num in nums:
if num in dic: return num
dic.add(num)
return -1
完整代码示例可查看:sword_for_offer/docs/剑指 Offer 03. 数组中重复的数字.md
复杂度分析
- 时间复杂度:O(N) - 只需遍历一次数组
- 空间复杂度:O(N) - 最坏情况需存储所有不重复元素
方法二:原地索引交换法
算法突破点
题目特殊条件:所有数字都在0 ~ n-1范围内,意味着数组元素与索引存在一一对应关系,可通过索引重排实现原地去重。
核心思路
通过交换操作将每个元素放到其对应索引位置,当发现目标索引已存在相同元素时,即为重复值。
操作流程
- 遍历数组,设当前索引为i:
- 若
nums[i] == i:元素已在正确位置,继续下一个 - 若
nums[nums[i]] == nums[i]:发现重复,返回该元素 - 否则:交换
nums[i]与nums[nums[i]]
- 若
动图演示
<
>
代码实现
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
i = 0
while i < len(nums):
if nums[i] == i:
i += 1
continue
if nums[nums[i]] == nums[i]: return nums[i]
nums[nums[i]], nums[i] = nums[i], nums[nums[i]]
return -1
复杂度分析
- 时间复杂度:O(N) - 每个元素最多交换两次
- 空间复杂度:O(1) - 无需额外空间
两种方法对比与选择建议
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 哈希表法 | O(N) | O(N) | 数据范围无限制时 |
| 原地交换法 | O(N) | O(1) | 元素范围0~n-1的特殊数组 |
扩展练习与项目资源
相似题型推荐
项目完整代码
- Python实现:sword_for_offer/codes/python/
- C++实现:sword_for_offer/codes/cpp/
- Java实现:sword_for_offer/codes/java/
刷题计划
建议结合项目中的剑指 Offer 刷题计划.md进行系统训练,按题目分类.md逐步攻克数组、链表、树等数据结构类型题。
掌握这两种方法后,数组去重类问题就能迎刃而解。收藏本文,下次遇到类似问题直接套用,让你的代码既高效又优雅!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



