LCR 120-寻找文件副本

57 阅读1分钟

题目

设备中存有 n 个文件,文件 id 记于数组 documents。若文件 id 相同,则定义为该文件存在副本。请返回任一存在副本的文件 id

  示例 1:

输入: documents = [2, 5, 3, 0, 5, 0]
输出: 0 或 5

  提示:

  • 0 ≤ documents[i] ≤ n-1
  • 2 <= 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