Что будет самой сложной для сортировки n
строк, имеющих n
символов каждый? Будет ли это всего лишь n
раз больше. случай O(n log n)
или что-то еще ...?Сортировка строк с использованием Merge Sort
ответ
Как @orangeoctopus, используя стандартный алгоритм ранжирования в коллекции n
строки размером n
приведут к вычислению O(n^2 * logn)
.
Однако - обратите внимание, что вы можете сделать это в O(n^2)
, с изменениями на radix sort.
Самый простой способ сделать это [по-моему] - это
- построить trie и заполнить его со всеми строками. Ввод каждая строка
O(n)
и вы делаете этоn
раз - всегоO(n^2)
- сделать DFS на синтаксическом дереве, каждый раз, когда вы столкнетесь знаком для конца для строки - добавьте его в отсортированную коллекцию. Порядок строк, добавленных таким образом, лексикографически, поэтому ваш список будет отсортирован лексикографически, когда вы закончите.
Легко видеть, что вы не можете сделать это лучше тогда O(n^2)
, так как только чтение данных является O(n^2)
, таким образом, это решение является оптимальным с точки зрения большой нотации O сложности времени.
Я думаю, вместо того, чтобы говорить «DFS», говорить «предварительный обход» будет более понятным. – CEGRD
Can 'O (n^2)' достигается без использования trie также? – Kshitij
@Kshitij Да, сделайте сортировку радикса в строке, trie - просто предложение - здесь будет работать стандартная сортировка радикса - с использованием символов (или их битового представления) каждой итерации для достижения текущего частичного порядка, пока вы не исчерпаете все биты /персонажи. Это также займет «O (n^2)». – amit
Когда вы говорите о нотации O
с двумя вещами различной длины, обычно вы хотите использовать разные переменные, например M
и N
.
Таким образом, если слияние сортировка O(N log N)
, где N
это число строк ... и сравнение двух строк является O(M)
где M
весы с длиной строки, то вы останетесь с:
O(N log N) * O(M)
или
O(M N log N)
, где M
длина строки и N
это количество строк. Вы хотите использовать разные ярлыки, потому что они не означают одно и то же.
В странном случае, когда средняя длина строки масштабируется с числом строк, как если бы вы имели матрицу, хранящуюся в строках или что-то вроде этого, можно утверждать, что M = N
, и тогда вам придется O(N^2 log N)
Не имеете в виду «O (M) где M ...» вместо «O (N) где N ...»? И в то время как в худшем случае производительность, как и требовалось, следует отметить, что средняя производительность случая для сравнения двух строк - это O (1), поскольку она становится геометрически меньшей и менее вероятно, что вам нужно будет посещать каждый дополнительный символ в строках. – xan
Конечно, я имел в виду их отдельно, но я изменил его, чтобы использовать 'M', чтобы быть более ясным. Он просит «худшую сложность», но дает «средний» размер жало ... так что все равно O (N), правильно? –
Да, вопрос немного неясен с его смешением худшего и среднего. Я думаю, что ваш ответ будет более сильным, чтобы охватить оба. – xan
Сортировка n элементов с помощью MergeSort требует сравнения O(N LogN)
. Если время для сравнения двух позиций - O(1)
, тогда общее время работы будет O(N logN)
. Однако для сравнения двух строк длины N требуется O(N)
времени, поэтому наивная реализация может зависеть от O(N*N logN)
времени.
Это кажется расточительным, потому что мы не воспользовались тем фактом, что для сравнения есть только строки N
. Мы могли бы как-то препроцитировать строки, чтобы в среднем сравнение занимало меньше времени.
Вот эта идея. Создайте структуру Trie и поместите туда N строк. У trie будет O(N*N)
узлов и потребуется O(N*N)
времени на сборку. Пройдите дерево и поместите целое «ранжирование» на каждый узел дерева; Если R (N1) < R (N2), то строка, связанная с Node1, предшествует строке, связанной с Node2 в словаре.
Теперь перейдите к Mergesort, выполните сравнения в O(1)
, просмотрев Trie. Общее время работы будет O(N*N + N*logN)
= O(N*N)
Редактировать: Мой ответ очень похож на @amit. Однако я приступаю к объединению, где он продолжает работу с radixsort после этапа построения trie.
Поддерживаете ли вы также привязку указателей к трем узлам, чтобы получить доступ к этим рейтингам во время сортировки слияния? уточните пожалуйста. Кроме того, я думаю, вы также должны включить стоимость проезда. Таким образом, сложность должна быть O (N * N + N * N + N * logN). Если это так, то подход сортировки по методу радикса выглядит лучше, так как это O (N * N + N * N). – CEGRD
@CERGD: нотация Big O касается только асимптотического роста по размеру ввода; он не имеет дело с постоянными факторами, O (2 * N * N + NlogN) = O (N * N). Повторяя вопрос через несколько месяцев, ясно, что ответ Амита проще и быстрее. Тем не менее, я не согласен с вашим аргументом: единственный способ измерить фактическую производительность - использовать хронометр, а не смотреть на постоянные факторы в O-нотации. Есть даже случаи, когда алгоритм с большей функцией O() превосходит другую в практических ситуациях. –
- 1. Сортировка массива с использованием Merge Sort
- 2. Merge Sort vs Selection Сортировка
- 3. Binary Merge sort & Natural Merge sort
- 4. merge part in merge sort
- 5. merge sort with insertion sort
- 6. Templated Quick/Merge Sort
- 7. Merge Sort in String с использованием LinkedList
- 8. Merge sort recursions
- 9. Merge sort in Haskell
- 10. Java - Merge sort array
- 11. Подсчет сравнений с Merge Sort
- 12. Проблемы с Merge Sort Буг
- 13. Сортировка данных в списке с использованием .sort()
- 14. Связанный список Сортировка с использованием Bubble Sort
- 15. Сравнения в merge-sort
- 16. Python Merge Sort
- 17. Merge sort throws StackOverflowError
- 18. Broken Merge Sort
- 19. Внешняя память merge sort
- 20. C++ merge sort реализация
- 21. Merge sort Java Algorithm
- 22. Visual C++ Merge Sort
- 23. Java & Merge Sort
- 24. Merge Sort Implementation java
- 25. Merge Sort Program
- 26. Merge sort java.lang.StackOverflowError
- 27. Merge Sort (pthreads) C++
- 28. Java Recursive Merge Sort
- 29. Python merge sort
- 30. реализация merge sort C++
Что вы здесь? – uday
Непонятно, что вы просите. –
отредактировал мой вопрос ..... – Abhishek