📜  门| GATE-CS-2016(套装1)|第 38 题(1)

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

题目描述

给定一个由非负整数组成的数组a。定义一个正数k,使得数组中每个元素a[i]都能够整除k。你的任务是找到k的最小值。如果这样的k不存在,则返回-1。

函数签名
def find_k(a: List[int]) -> int:
    pass
输入
  • 整数n,表示数组a的长度。
  • 长度为n的非负整数数组a,表示给定的数组。
输出
  • 一个整数,表示k的最小值。
示例
示例1

输入:

4
4 8 16 32

输出:

4
示例2

输入:

4
4 8 16 33

输出:

-1
解题思路

要求k能够整除数组中的每个元素,即数组中的每个元素都是k的倍数。因此,我们只需要求出数组中所有元素的最大公约数,即gcd。如果gcd是数组中任意两个元素的公约数,那么k就等于gcd;否则,k不存在。

注意,因为第一个元素a[0]可能为0,所以在求gcd时,需要先将数组去掉0元素再求。

代码实现
from typing import List
from math import gcd

def find_k(a: List[int]) -> int:
    # 去掉0元素
    a = [x for x in a if x != 0]
    # 如果去掉0后数组为空,则返回-1
    if not a:
        return -1
    # 求出所有元素的最大公约数
    g = a[0]
    for x in a:
        g = gcd(g, x)
    # 如果gcd是数组任意两个元素的公约数,则k等于gcd;否则,k不存在
    for x in a:
        if x % g != 0:
            return -1
    return g
复杂度分析

假设数组a的长度为n。

  • 时间复杂度:先去掉0元素,需要遍历整个数组,时间复杂度是O(n);然后求出所有元素的最大公约数,需要遍历整个数组,时间复杂度是O(n);最后检查gcd是否是数组中任意两个元素的公约数,需要遍历整个数组,时间复杂度是O(n)。因此,总时间复杂度是O(n)。
  • 空间复杂度:只需要常数个变量存储数组元素和最大公约数,所以空间复杂度是O(1)。