📜  门| GATE-CS-2004 |问题22(1)

📅  最后修改于: 2023-12-03 14:58:26.319000             🧑  作者: Mango

题目描述

给定一个包含n个整数的数组A,其中每个整数的绝对值都小于n,确定A中是否存在重复的元素。你可以假设n始终大于或等于2。

例如,如果n = 3,展示出一个可以合法地回答该问题的A数组。如果n=2,你需要证明无法构造所有数组。

解题思路

题目中给定的重点是“每个整数的绝对值都小于n”,这意味着该数组可能包含负数。但是数组中不可能存在绝对值大于n-1的元素,因此我们可以将数组中的每个负数都加n,这样可以将其转化为正整数,而对于正整数,我们则不需要做任何处理。

然后,我们可以使用桶排序,将元素放入桶中,并检查每个桶是否已经存在元素。如果某个桶已经存在元素,则该元素已经出现过两次,我们可以立即返回true。如果我们没有找到任何重复的元素,则可以返回false。

我们需要创建n个桶,因为该数组中的元素的值可以为0到n-1。因此,桶的大小应为n。

def check_duplicate(n: int, a: List[int]) -> bool:
    # 加 n,按顺序放入桶
    buckets = [0] * n
    for x in a:
        index = abs(x) % n
        if a[index] >= n:
            return True
        buckets[index] += n  # 加n,使其转化为非负整数
    return False

测试样例

这里给出几组测试样例。

测试集case1

输入:

n = 6,a = [2, 6, 0, -8, -2, 5]

输出:

True

解释:

学习者可以将负数转化为正整数,然后按编号放入桶中。在给定的数组中,一个元素可能会经过转换,成为位于同一索引的另一个元素,因此我们需要检查获同一索引的元素是否已经存在。这里存在重复项,其中包括 2 和 -8。我们在加上n的操作之后,还需判断是否大于n,由于2和-8的绝对值都小于6,所以加n之后不会大于6,而我们的桶大小为6,因此只需要判断是否大于等于n即可。

测试集case2

输入:

n = 5,a = [1, 2, 3, 4, 2]

输出:

True

解释:

在第二个和第五个元素中发现重复项。因此,我们返回True。

测试集case3

输入:

n = 3,a = [2, 0, 1]

输出:

False

解释:

没有找到重复项,所以返回False。