题目
设备中存有 n 个文件,文件 id 记于数组 documents。若文件 id 相同,则定义为该文件存在副本。请返回任一存在副本的文件 id。
示例 1:
输入: documents = [2, 5, 3, 0, 5, 0]
输出: 0 或 5
提示:
0 ≤ documents[i] ≤ n-12 <= n <= 100000
思路
解法一:哈希表统计数字频次
思路
hash表统计出每次数字出现的频次,返回第一个>1的副本。
时间复杂度:O(N) 空间复杂度:O(N)
代码一:哈希表统计
class Solution:
def findRepeatDocument(self, documents: List[int]) -> int:
t = {}
for i in documents:
if i not in t:
t[i] = i
else:
return i
return -1
解法二:原地置换算法
原地置换思路
从头到尾依次扫描这个数组,当扫描到下标为i的数字,首先比较documents[i]是否等于i:
- 如果是,扫描下一个
- 如果不是,将m和documents[m]的数字进行比较
- 如果documents[i]==docuemtns[m],找到重复数字
- 如果documents[i]!=docuemtns[m],交换这两个数字,继续进行比较
时间复杂度:O(N) 空间复杂度:O(1)
代码二:原地置换
class Solution:
def findRepeatDocument(self, documents: List[int]) -> int:
n = len(documents)
for i in range(n):
if documents[i] == i:
continue
while documents[i] != i:
if documents[i] == documents[documents[i]]:
return documents[i]
documents[documents[i]], documents[i] = documents[i], documents[documents[i]] # 交换的顺序千万不可以写错,documents[documents[i]]必须在前面
return -1