Учитывая два массива одинакового размера, найдите пару элементов из обоих массивов, которые составляют сумму с наименьшим абсолютным значением

#arrays #algorithm

#массивы #алгоритм

Вопрос:

Вчера мне было поручено решить эту проблему, и с тех пор я пытался найти для нее эффективное решение.
Деталь решения такова: учитывая два массива a [n], b [n], найдите пару (a [i],b [j]) так, чтобы abs (a [i] b [j]) было как можно меньше. Два массива состоят из целых элементов, не превышающих 1 миллиарда, а n здесь не более 10000.
Я знаю, что решение, состоящее из двух циклов for, здесь непрактично, поскольку размеры массивов меньше или равны 10000.
Я думаю о решении, в котором я буду сортировать эти элементы способом, который я еще не выяснил, чтобы мы могли легко определить сумму, которая имеет наименьшее абсолютное значение, поскольку мой класс изучает алгоритмы сортировки.
Можете ли вы помочь мне разобраться в этом.
PS: Извините, я не могу ввести здесь математические символы.

Комментарии:

1. я полагаю, что элементы являются целыми числами?

2. Требуется ли вам найти два элемента с наименьшей суммой? Вот как я это понимаю.

3. Разве это не просто min(array_1) min(array_2) ?

4. Не могли бы вы описать проблему более подробно (понятно) и добавить некоторые демонстрационные данные

5. Вы хотите максимизировать |a b| , где a из первого массива, а b из второго массива?

Ответ №1:

У меня есть Python код, который решает проблему за O(nlogn mlogm) O(m n) = O(nlogn mlogm) time, где n — длина первого массива и m — длина второго массива. Вот код:

 arr1.sort()
arr2.sort(reverse = True)
n = len(arr1)
m = len(arr2)
print arr1
print arr2
minim = abs(arr1[0]   arr2[0])

i = 0
j = 0

while i<n and j<m:
   minimum = abs(arr1[i]   arr2[j])
   minim = min(minim,minimum)
   if arr1[i]>0 and arr2[j]>0:
      j  = 1
   elif arr1[i]<=0 and arr2[j]<=0:
      i  = 1
   elif arr1[i]>0 and arr2[j]<=0:
      if abs(arr1[i]) > abs(arr2[j]):
          j  = 1
      else:
          i  = 1
   elif arr1[i]<=0 and arr2[j]>0:
      if abs(arr1[i]) > abs(arr2[j]):
          i  = 1
      else:
          j  = 1

print minim
  

Пример:

arr1[] = [-23, -10, 30, 44, 45]

arr2[] = [61, 55, 32, 22, -55]

Ответ: 1

Ответ №2:

Вы можете отменить один из списков и отсортировать его вместе с другим списком. В этом новом списке вы ищете две последовательные записи с наименьшим расстоянием и такие, чтобы две записи были по одной из каждого исходного списка.

Если a[i], i=0,1,...,n первое и b[j], j=0,1,...,n второе, то min(|a[k] b[l]|)=min(|a[k]-(-b[l])|) . Таким образом, вместо минимизации суммы a[k] и b[l] для некоторых k,l мы можем минимизировать разницу между a[k] и -b[l] для некоторых k,l . Итак, мы ищем пару a[k] , -b[l] как можно ближе друг к другу. Такая пара должна быть последовательной в списке, полученном в результате сортировки a[i], -b[j] i,j=0,1,...,n в один список c[t] длины 2n .

Сортировка c — O (n log n), прохождение c — O (n), поэтому во времени выполнения преобладает сортировка.

Комментарии:

1. что, если нет последовательных чисел, так что одно из чисел из массива 1, а другое из массива 2??

2. @User_Targaryen Этого не может произойти, поскольку объединенный список упорядочен линейно. Если наименьшая запись в объединенном списке array3, полученная в результате сортировки array1 и -array2, из первого массива, то наименьшая запись из -array2 должна отображаться с некоторым индексом i> 0 . Тогда array3[i-1] и array3 [i] — это пара последовательных записей, одна из array1 и одна из array2. Аналогичный аргумент работает, если наименьшая запись в array3 из -array2 . Однако эта пара не обязательно должна иметь наименьшее расстояние.

3. Пусть a=[1,2,3,4,5] и b=[6,7,8] , поэтому окончательный ответ = 1. По вашему методу ваш третий массив будет выглядеть так [-8,-7,-6,1,2,3,4,5] . Теперь, как вы найдете ответ, 1 используя свой метод? Пожалуйста, объясните

4. @User_Targaryen Как вы получаете 1 сумму элемента a и b ?

5. @User_Targaryen Нет. ОП запрашивает min(abs(a[i] b[j])) , что 1 6=7 в вашем примере.