Для этой задачи ваш код должен принять два отсортированных массива целых чисел X и Y в качестве входных данных. Он должен вычислить сумму абсолютных расстояний между каждым целым числом в X и его ближайшим числом в Y.
Примеры:
X = (1 5,9)
Y = (3,4,7)
Расстояние 2 + 1 + 2.
X = (1,2,3)
Y = (0,8)
Расстояние составляет 1 + 2 + 3.
Ваш код может принимать данные любым удобным для вас способом.
Основным ограничением является то, что ваш код должен выполняться за линейное время в сумме длины двух массивов. , (Можно предположить, что добавление двух целых чисел занимает постоянное время.)
1 + 2 + 3
происходит отX = (1,2,3)
иY = (0,8)
?1
,2
и3
вY
ИБ0
. Таким образом, различие1-0
,2-0
,3-0
.Ответы:
Haskell ,
7064 байтаПопробуйте онлайн!
объяснение
Сначала мы определяем
(%)
абсолютную разницу между двумя числами. Затем мы определяем(#)
интересную функцию. В первой строке мы сопоставляем, когда оба списка не пусты:На нашем первом случае из здесь мы привязываем
d
кe:_
сe:_<-d
. Это гарантирует, чтоd
это не пусто и устанавливает его первый элемент вe
.Тогда , если второй элемент ( ) ближе , чем первый ( ) к первому элементу X ( ), мы возвращаем удаление первого элемента Y и повторный вызов с тем же X .Y Икс Y Икс
e
c
a
x#d
Если мы сопоставляем шаблон, но не выполняем условие, которое мы выполняем:
Что, удаляет первый элемент и добавляет его абсолютную разницу от первого элемента X к оставшемуся результату.Икс Икс
Наконец, если мы не соответствуем шаблону, мы возвращаем . Несоответствие шаблону означает, что X должен быть пустым, потому что Y не может быть пустым.0 Икс Y
Этот алгоритм имеет обозначение порядка .O ( | X| + | Y| )
Haskell , 34 байта
Вот как я бы сделал это за время:O ( | X| × | Y| )
Попробуйте онлайн!
источник
Python 2 ,
124120 байтПопробуйте онлайн!
Сохранено 4 байта при переходе к программе или функции.
Соблюдение ограничения сложности времени возможно, потому что оба списка отсортированы. Обратите внимание, что каждый раз вокруг цикла либо
i
увеличивается, либоj
увеличивается. Таким образом цикл выполняется в большинствеlen(X)+len(Y)
случаев.источник
C (gcc), 82 байта
Это принимает входные данные в виде двух целочисленных массивов и их длины (поскольку в противном случае C не может получить их длину). Это может быть показано , что работать в
O(a+b)
потому что либоa
илиb
уменьшается на каждой итерации цикла, который заканчивается , когдаa
достигает0
(иb
не может быть уменьшен ниже0
).Попробуйте онлайн!
Некоторые заметки:
Вместо индексации в массивах, приращение указателей и разыменование напрямую сохраняет достаточно байтов, чтобы оно того стоило (
*x
противx[a]
иy[1]
противy[b+1]
).В
--b&&
проверяет состояние дляb>1
окольным путем - еслиb
есть1
, то будет нулевое значение. Поскольку это модифицируетb
, нам не нужно изменять его в первой ветви троичного (который продвигаетсяy
), но нам нужно изменить его обратно во второй (который продвигаетсяx
).Никаких
return
заявлений не требуется, потому что черная магия. (Я думаю, это потому, что последним оператором, который будет оцениваться, всегда будетn+=...
выражение, которое использует тот же регистр, что и регистр, используемый для возвращаемых значений.)источник
Рубин, 88 байт
Попробуйте онлайн!
Кроме того, для удовольствия, более короткая анонимная функция, которая не совсем соответствует ограничениям сложности:
источник
[5, 6], [0, 1, 5]
.JavaScript (Node.js) , 80 байт
x
,y
передаются по ссылке, которые не копируют содержимое1/v
является ложным, еслиx[i]
находится вне диапазона, правда в противном случаеt
->d>y[j+1]-v
->v+v>y[j]+y[j+1]
ложно, если выполняются следующие условия. А это означаетy[j]
, что число является ближайшим кv
вy
v
меньше(y[j]+y[j+1])/2
илиy[j+1]
находится вне диапазона, который будет преобразован вNaN
и сравнить сNaN
доходностьюfalse
>
знак, чтобы сохранить еще 1 байтt
всегда логическое значение, и*
преобразовать его в0
/1
перед вычислениемПопробуйте онлайн!
источник
Mathematica, 40 байт
Если вы должны создать полную программу, с входами:
Вот время до 1000000 точек (выборка каждые 10000) для
y
:Близко к линейному.
источник