【问题标题】:Maximum Gcd and Sum最大 Gcd 和总和
【发布时间】:2017-07-24 10:38:14
【问题描述】:

给定两个数组AB,每个数组包含n个元素。选择一对元素 (x, y) 使得:
x 属于数组 A
y 属于数组B
• GCD(x, y) 是所有对中的最大值 (x, y)。
如果有不止一对这样的对具有最大 gcd,则选择总和最大的一对。打印这个最大和对的元素之和。

这是来自 Hackerrank weekofcode34 的问题。

from fractions import gcd

from itertools import product
n = int(input().strip()) #two arrays of equal length
A = set(map(int, input().strip().split(' '))) #array1
B = set(map(int, input().strip().split(' '))) # arry2
output_sum=[]
output_GCD=[]
c=list(product(A,B))
for i in c:

    temp1=i[0]
    temp2=i[1]

    sum_two=temp1+temp2

    temp3=gcd(temp1,temp2)
    output_GCD.append(temp3)
    output_sum.append(temp1+temp2)
temp=[]
for i in range(len(output_GCD)):
  if(output_GCD[i]==max(output_GCD)):
    temp.append(output_sum[i])
print(max(temp))

此解决方案适用于较小的条件,并且我在大多数测试用例中都超时,请帮助我如何改进我的解决方案。

【问题讨论】:

  • 不确定这是否更快,但不是计算每一对的 GCD (O(n²)),也许只是计算 A 中所有数字的所有除数,将它们存储在映射中 @ 987654323@,然后对于 B 中的所有数字,再次计算所有除数并获得地图中已经存在的最大除数。
  • 您可以在每个数组中删除与除法相关的非最大元素以减少比较次数。

标签: algorithm python-3.x greatest-common-divisor


【解决方案1】:

您可以通过以下方式计算数组A 的所有除数a_divisors

# it is not real python-code, just ideas of algorithm
count = {}
for (i : A): 
  count[i]++

a_divisors = {}
for (i : range(1, 10^6)):
  for (j = i * i; j <= 10^6; j += i):
    if j in count.keys():
      a_divisors[i] = 1

在您可以为B 构造相同的数组b_divisors 并从两个数组中选择共同的最大值之后

例如:

5
3 1 4 2 8
5 2 12 8 3

产生除数数组:

a: 1, 2, 3, 4, 8
b: 1, 2, 3, 4, 5, 6, 8, 12

常见的最大值是:4

如果您知道 gcd(a, b) = 4,那么您只需从 A 中选择 1 个具有除数 4 的最大值和从 B 中选择 1:8 + 12 = 16

【讨论】:

  • 第二部分似乎还可以,但我确信有比测试所有数字直到某个任意上限更有效的方法来确定所有除数。
  • 没有任何除法和和/乘法真的很快,但是 Key-Map 并不快。首先,我认为将 Key-Map 替换为掩码长度为 10^6 的数组确实更好,它显着提高了速度。第二个想法是在第一个范围循环中使用sqrt(10^6) = 10^3,并添加a_divisor[j / i ]a_divisor[i]
  • 没有划分,但仍有非常很多测试。如果其中一个数组中的最大数是 10^100 怎么办?你还会使用 10^6 作为上限吗?或者测试所有高达 10^100 的数字?
  • tobias_k,保证每个A[i]B[i]不大于10^6
【解决方案2】:

您必须将 A 和 B 转换为 Set(以便在其中轻松找到)

def maximumGcdAndSum(A, B):
    A = set(A)
    B = set(B)
    max_nbr = max(max(A), max(B))
    i = max_nbr

    while i > 0:  # for each i starting from max number
        i_pow = i  # i, i^2, i^3, i^4, ...
        maxa = maxb = 0

        while i_pow <= max_nbr:  # '<=' is a must here
            if i_pow in A:
                maxa = i_pow  # get the max from power list which devides A
            if i_pow in B:
                maxb = i_pow  # get the max from power list which devides B
            i_pow += i
        if maxa and maxb:
            return maxa + maxb  # if both found, stop algorithm
        i -= 1

    return 0

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多