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)。