Насколько я понимаю, проблема состоит в том, чтобы найти два уникальных элемента в массиве, расстояние между которыми (разность индексов) является максимальным, и вернуть расстояние, на которое они разделены.Я возвращаю nil
, если все элементы одинаковы.
Мое решение пытается минимизировать количество пар элементов, которые необходимо проверить, прежде чем будет найдено оптимальное решение.Для примера, приведенного в вопросе, необходимо рассмотреть только две пары элементов.
def calc_res(a)
sz = a.size-1
sz.downto(2).find { |n| (0..sz-n).any? { |i| a[i] != a[i+n] } }
end
a = [4,6,2,2,6,6,4]
calc_res a
#=> 5
Если sz = a.size-1
, sz
- максимально возможное расстояние, два элемента могут быть разделены.Если, например, a = [1,2,3,4]
, sz = 3
, то есть количество позиций 1
и 4
, находятся на расстоянии друг от друга.
Для a
, sz = a.size-1 #=> 6
.Сначала я определяю, являются ли какие-либо пары элементов, которые находятся на расстоянии n = sz
, уникальными.[a[0], a[6]] #=> [4,4]
является единственной парой элементов 6
, расположенных отдельно.Поскольку они не уникальны, я уменьшаю n
на единицу (до 5
) и исследую все пары элементов на n
позиции друг от друга, ища тот, чьи элементы являются уникальными.Различаются две пары 5
позиций: [a[0], a[5]] #=> [4,6]
и [a[1], a[6]] #=> [6,4]
.Оба они соответствуют тесту, поэтому мы закончили и возвращаем n #=> 5
.Фактически мы закончили тестирование первой из этих двух пар.Если бы ни эти пары не содержали уникальных значений, n
было бы уменьшено на 1
до 4
, а три пары [a[0], a[4]] #=> [4,6]
, [a[1], a[5]] #=> [6,6]
и [a[2], a[6]] #=> [2,6]
были бы найдены для поиска одной с уникальными значениями и т. Д..
См. Integer # downto , Enumerable # find и Enumerable # any? .