LeetCode 剑指 Offer 03. 数组中重复的数字 原地部分有序化题解,理解、内化巧妙思路。
题目
剑指 Offer 03. 数组中重复的数字
https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
Set集合解
Set
(基于Map
)非常适合用来数据查重、判断是否存在O(1)
,相比使用List
结构判断contains
复杂度最优。
复杂度分析
时间
遍历一次给定数组,时间复杂度O(n)
。
空间
使用了额外的Set
集合,空间复杂度O(n)
。
代码
|
|
原地部分有序化题解
上述使用Set
求解,我们未充分利用题干已知条件:
长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内
思路
- 取值
0~n-1
的数据,并且数组长度为n
,并且其中存在重复元素 - 已知数组给定是无序的,那么我们尝试有序化,同时,将元素值、元素下标一一对应上
- 基于上述操作,重复元素在有序化时,第二次一定会产生下标冲突!
- 有序化具体操作:
- 我们以
i
表示数组遍历下标,尝试将当前nums[i]
下标有序化; i==nums[i]
时,说明当前元素值与下标本身就是匹配的,我们挪动i
;i!=nums[i]
时:- 将下标为
nums[i]
的元素值替换为i
,同时将原下标nums[i]
元素值交换到i
位置; - 如果上述替换操作时发现,
nums[i]
下标位置的元素值已经是i
了,说明是原先已经有一个i
值(也可能是刚刚交换过去的),此时即求得重复元素;
- 将下标为
- 我们以
这个思路下,一是利用了题干的已知条件,二,实现中未利用多余的集合空间,交换操作也只有O(1)
复杂度。
代码
|
|
复杂度分析
时间
最差也仅需遍历完数组,时间复杂度为O(n)
。
空间
本算法操作为原地操作,空间复杂度O(1)
。