2015-04-09 4 views
0

Идентичный пара в массиве 2 индексов p,q таким образом, чтоПодсчет количества идентичных пар

0<=p<q<N и array[p]=array[q] где N длина массива.

Учитывая несортированный массив, найдите число одинаковых пар в массиве.

Моим решением было сортировать массив по значениям, отслеживать индексы.

Тогда для каждого индекса p в отсортированном массиве, посчитайте все q<N таким образом, что и

sortedarray[p].index < sortedarray[q].index and 
sortedarray[p] = sortedarray[q] 

Является ли это правильный подход. Я думаю, что сложность будет

O(N log N) for sorting based on value + 

O(N^2) for counting the newsorted array that satisfies the condition. 

Это значит, что я все еще смотрю O(N^2). Есть ли способ лучше ?

Еще одна мысль, которая пришла, заключалась в том, что каждый P-бинарный поиск сортировал массив для всех Q, который удовлетворяет условию. Разве это не уменьшить сложность второй части к O(Nlog(N))

Вот мой код для второй части

for(int i=0;i<N;i++){ 

        int j=i+1; 

      while(j<N && sortedArray[j].index > sortedArray[i].index && 
        sortedArray[j].item == sortedArray[i].item){ 

         inversion++; 
         j++; 
      } 
     } 
    return inversion; 

@Edit: Я думаю, я перепутал сложность второй части будет O(N^2).

Как и в каждой итерации во время цикла, не происходит повторного сканирования элементов из индексов 0-i, для сканирования отсортированного массива для подсчета инверсий требуется линейное время. Таким образом, общая сложность

O(NlogN) для сортировки и O(N) для линейного сканирования в сортированном массиве.

+0

Поскольку сортировка объединяет одинаковые значения, вам не нужно проверять все 'q', только те, которые находятся рядом с' p'. Если вы используете стабильный алгоритм сортировки, вам даже не нужно выполнять первый тест. –

+0

Правильно, мне нужно будет проверить значения вблизи p, для каждого p из 0

sreeprasad

+0

Тот факт, что массив отсортирован, подразумевает что вы можете сканировать его за один проход. Таким образом, это не O (n^2), а O (n). В качестве примера счетчика сортировка вставки - это O (n^2), потому что для каждого элемента он должен сканировать весь массив. – mdm

ответ

3

Вы частично верны. Сортировка массива с помощью Merge Sort или Heapsort займет O(n lg n). Но как только массив отсортирован, вы можете сделать один проход, чтобы найти все одинаковые пары. Этот единственный проход является операцией O(n). Таким образом, общая сложность:

O(n lg n + n) = O(n lg n)

+0

Я думаю, что один проход не даст всех значений, он даст мне подсчет всех последовательных значений в sortedarray, который удовлетворяет условию. – sreeprasad

+0

Насколько сложно найти одинаковые пары в этом массиве: '[1, 5, 7, 7, 10, 13, 13, 20]'? –

+0

Тим, не могли бы вы сослаться на мой код, возможно, я пропустил вашу точку зрения, но я не вижу инварианта линейной временной стоимости для второй части. – sreeprasad

0

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

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

Если количество допустимых значений является целым и в ограниченном диапазоне, вы можете напрямую использовать массив вместо хеш-таблицы. Индекс значения i составляет i. В этом случае сложность будет O(n+m), где m - это число допустимых значений (потому что вы должны сначала установить 0 все записи в массиве, а затем просмотреть все записи массива для подсчета пар).

Оба метода дают вам количество одинаковых значений для каждого значения в вашем массиве. Назовем этот номер nv_i номером появления значения i в массиве.Затем число пар значений i: (nv_i)*(nv_i-1)/2.

Вы можете спарить:

1st i with nv_i-1 others 
2nd i with nv_i-2 others 
... 
last i with 0 

И (nv_i-1)+(nv_i-2)+...+0 = (nv_i)*(nv_i-1)/2

+0

нам нужна еще одна карта хэша, Wont линейное сканирование дает мне счет индексов, которые удовлетворяют условию. Пожалуйста, напишите мой код и комментарии TIm и mdm – sreeprasad

+0

@SREEPRASADGOVINDANKUTTY Если вы отсортируете массив, вам не нужен хэш-файл. Вы можете просто запустить массив и вычислить 'nv_i'.Но hashmap предоставит вам все 'nv_i' без сортировки. Итак, вы переходите от 'O (n * log (n))' to 'O (n)' для всего алгоритма. – fjardon

+0

Как вы обновляете счетчик? Не может быть частоты того, как часто значение рассматривается, поскольку условия индексов и значений могут не выполняться. – sreeprasad

1

Как Тим отмечает в своем ответе, сложность нахождения пары в отсортированном массиве O(n) и не O(n^2).

Чтобы убедиться в этом, подумайте о типичном алгоритме O(n^2): Insertion Sort.

Анимированный пример можно найти here.

Как вы можете видеть в формате GIF, поэтому этот алгоритм является квадратным, потому, что для каждого элемента, он должен проверить весь массив, чтобы гарантировать, где такой элементу придется идти (это включает предыдущих элементов в массиве!).

В руке у вас есть упорядоченный массив: например. [0,1,3,3,6,7,7,9,10,10]

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

Таким образом, вы сканировать весь массив только один раз: O(n)

+1

Это означает, что я принял сложность кода для второй части как O (N^2). Поскольку мой индекс «j» всегда больше индекса «i», не происходит повторного сканирования элементов из 0-i, а сложность - это O (N). Верный ? – sreeprasad

+0

@SREEPRASADGOVINDANKUTTY Правильно! – mdm

0

Я думал об этом .... Я думаю, что если вы «встраивать» условие == в свой алгоритм сортировки, то, сложность все еще O (n lg n).

Смежные вопросы