Времето на изпълнение на описания алгоритъм е O(n^2)
. Външният цикъл се изпълнява n/2
пъти, като по този начин вътрешният брояч j
се нулира n/2
пъти и по този начин вътрешният цикъл се изпълнява общо O(n^2)
пъти.
Не съм сигурен, че следвам логиката зад вашата идея, но ето два подхода как бих я приложил [в псевдокод на високо ниво]:
(1) създайте хистограма от данните:
- създайте
Map<Integer,Integer>
[ключът е елементът и стойността е броят на срещанията]
- итерирайте масива и за всеки елемент пребройте колко пъти се появява
- повторете хистограмата и намерете дали има уникален максимум.
- Ако има - връща true, иначе връща false.
Този подход е средно O(n)
, ако използвате HashMap
a> като картата.
(2) сортиране и намиране на макс.
- Сортирайте масива - като резултат всички равни елементи са съседни един на друг. Можете да използвате
Arrays.sort(array)
за сортиране.
- Пребройте колко пъти се появява всеки елемент [подобно на идеята за хистограмата] и намерете дали има уникален максимум. Всъщност не е необходимо да поддържате данните за всички елементи, достатъчно е да поддържате първите 2 и накрая да видите дали са идентични.
Това решение е O(nlogn)
среден + най-лошият случай [всъщност, в зависимост от сортирането - сливане sort ви дава O(nlogn)
най-лошия случай, докато бързото сортиране ви дава O(n^2)
най-лошия случай, като и двата са O(nlogn)
средния случай ].
РЕДАКТИРАНЕ:
Разбрах погрешно проблема, мислех, че търсите дали има уникален максимум. Тези 2 решения все още са подходящи за проблема, просто трябва да промените последната стъпка на всяко [за да проверите дали най-често срещаният елемент се появява повече от половината пъти, което отново е сравнително лесно и изпълнимо в O(n)
].
Освен това има друго решение: използвайте алгоритъм за избор, за да намерите медианата, и след като я намерите, проверете ако е мажоритарен елемент и връщане, ако е такъв. Тъй като алгоритъмът за избор е базирано на разделяй и владей решение, мисля, че отговаря на вашите нужди.
person
amit
schedule
14.04.2012