Эффективное определение количества меньших элементов для каждого элемента в массиве


9

Я застрял на этой проблеме:

Для заданного массива из первых натуральных чисел, произвольно переставленных, строится массив , так что - это число элементов от до которые меньше, чем , AnBB(k)A(1)A(k1)A(k)

я) Учитывая вы можете найти в времени? II) Учитывая вы можете найти в времени?ABO(n)
BAO(n)

Здесь . Для конкретного примера: B(1)=0

|A843172965B000031644|

Может кто-нибудь мне помочь? Спасибо.


Я нашел это: Вычисление кодировок перестановок, которое дает алгоритмы для этих задач. По крайней мере, я думаю, что это те же проблемы. O(nlogn)
Реал Слав

@Merbs означает, что подсказка, которую вы дали, означает, что у вас есть решение?
AJed

1
@ AJed, это означает, что у меня есть алгоритм, хотя для простого алгоритма без пробела требуется и если нам разрешено пространство. В данный момент я склоняюсь к тому, что ни один из них невозможен в и оба являются одним и тем же алгоритмом. O(n2)O(nlogn)O(n)
Merbs

@Merbs. Я чувствую, что ваш намек может привести к правильному пути. У меня тоже есть одно решение (следуя вашей подсказке). Я предполагаю, что в анализе есть хитрость, которая заставляет его перейти к . Я думаю, что хитрость - это знание того, что идет только от 1: . O(n)An
AJed

2
Эта статья также дает алгоритм . Вы уверены, что для этого существует алгоритм ? O ( n )O(nlogn)O(n)
Реал Слав

Ответы:


1

Наивный алгоритм определения из :ABA

Для , определите значение путем сравнения каждого с для и подсчета тех, которые удовлетворяют .B ( k ) A ( i ) A ( k ) i = 1 , , k A ( i ) < A ( k )k=1,,nB(k)A(i)A(k)i=1,,kA(i)<A(k)

Этот алгоритм сравнивает со всеми остальными ( раз), с другими и т. Д., Поэтому общее количество сравнений равно . Но это не лучшее, что мы можем сделать. Например, глядя на , нам не нужно делать никаких сравнений! потому что это первые натуральных чисел, и гарантируется (независимо от перестановки), что там будут младших натуральных чисел. А как насчет ? Вместо проверки от до мы могли бы просто проверить . Это:n - 1 A ( 2 ) n - 2 ( n - 1 ) ( n - 2 )A(1)n1A(2)n2 B(n)B(n)=A(n)-1nn-1B(n-1)A(1)A(n-2)A(n)(n1)(n2)2B(n)B(n)=A(n)1 nn1B(n1)A(1)A(n2)A(n)

Для , используйте алгоритм выше; для используйте обратный алгоритм: определите , предварительно установив для него значение а затем вычтя для каждой записи для меньше . k=nk=1,,n2B(k)A(n)-11A(i)i=k+1,,nA(k)k=n2,,nB(k)A(n)11A(i)i=k+1,,nA(k)

Это займет шагов, которые все еще . Отметим также, что при построении из , если то . O(n2)ABB(n)=A(n)-1A(n)=B(n)+12×(n21)(n22)2=(n2)(n4)4O(n2)ABB(n)=A(n)1A(n)=B(n)+1

Но теперь для большей утонченности. Если нам разрешено дополнительное пространство или сортировка на месте, мы можем отсортировать числа, сравнивая их. Например:

|A843172965S987432165B0000316|

Вместо того, чтобы проверять их все (или проверять их по порядку), мы могли бы использовать бинарный поиск для определения каждого . Однако сортировка по-прежнему занимает время .O ( n log n )B(k)O(nlogn)


Это была только моя первая идея; хотя я понимаю, что проблема более интересна, чем я изначально ее считал. И у меня еще не было возможности прочитать результаты Realz Slaw, поэтому алгоритм может быть отключен.
Мерб

0

Вместо того, чтобы определять каждый одному за раз, мы можем смотреть в будущее и проходить каждое число в только один раз ! Но мы будем использовать пробел:A nB(k)A n

|A123456789B800000000104000011112030001222230101123333407011233345320123444561901234445666012344567450123456784|

Мы могли бы сэкономить еще больше времени, не обновляя те, которые уже были определены (то есть, нет смысла обновлять после первого шага), но в худшем случае нам все еще нужно обновить раза( n ) ( n + 2 )8(n)(n+2)2


0

и I и II разрешимы с помощью #next_greater_element, который я объяснил здесь . но это немного сложнее, чем просто проблема, но перед решением вам нужно изучить следующий более важный элемент:

  1. рассмотрим, что у нас есть вектор для каждого элемента из имя для элемента . теперь один раз запустите следующий больший алгоритм, начиная справа налево, но, кроме установки элемента в его следующего большего индекса элемента, вставьте в элементы, которые является их следующим большим элементом. Затем выполните итерацию по массиву слева направо, а затем где - размер вектора . и его потому что каждый следующий больший алгоритм равен а также повторениеASiiiASiiB[i]=j=0x(Si[j]+1)xSiΘ(n)Θ(n)Θ(n)

вторая часть также сходна отметить , что мы можем получить значение элемента , самый правый в EDIT: мое решение является неправильным, кажется , что не имеют каких - либо решениеO(1)o(n)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.