Przechowuj największe liczby 5000 ze strumienia liczb
Biorąc pod uwagę następujący problem:
"przechowuj największe 5000 liczb ze strumienia liczb"
Rozwiązaniem, które przychodzi na myśl, jest binarne drzewo wyszukiwania utrzymujące liczbę węzłów w drzewie i odniesienie do najmniejszego węzła, gdy liczba osiągnie 5000. Gdy liczba osiągnie 5000, każda nowa Liczba do dodania może być porównana z najmniejszym elementem w drzewie. Jeżeli jest większa, można dodać nową liczbę, wtedy najmniejsza usunięta i nowa najmniejszy obliczony (który powinien być bardzo prosty już mając poprzedni najmniejszy).
Mój problem z tym rozwiązaniem polega na tym, że drzewo binarne naturalnie zostanie wypaczone (ponieważ usuwam tylko z jednej strony).
Czy istnieje sposób na rozwiązanie tego problemu, który nie stworzy strasznie przekrzywionego drzewa?
W razie gdyby ktoś chciał, umieściłem pseudo-kod dla mojego rozwiązania do tej pory poniżej:
process(number)
{
if (count == 5000 && number > smallest.Value)
{
addNode( root, number)
smallest = deleteNodeAndGetNewSmallest ( root, smallest)
}
}
deleteNodeAndGetNewSmallest( lastSmallest)
{
if ( lastSmallest has parent)
{
if ( lastSmallest has right child)
{
smallest = getMin(lastSmallest.right)
lastSmallest.parent.right = lastSmallest.right
}
else
{
smallest = lastSmallest.parent
}
}
else
{
smallest = getMin(lastSmallest.right)
root = lastSmallest.right
}
count--
return smallest
}
getMin( node)
{
if (node has left)
return getMin(node.left)
else
return node
}
add(number)
{
//standard implementation of add for BST
count++
}
2 answers
Najprostszym rozwiązaniem jest utrzymanie sterty min o maksymalnym rozmiarze 5000.
- za każdym razem, gdy pojawia się nowa liczba-sprawdź, czy sterta jest mniejsza, a następnie 5000, jeśli tak-dodaj.
- Jeśli nie jest-sprawdź, czy minimum jest mniejsze, to nowe element, a jeśli tak, to wyskakuj i wstaw nowy element.
- kiedy skończysz-masz stertę zawierającą 5000 największych elementów.
Rozwiązanie to jest O(nlogk)
złożonością, gdzie n
jest liczba elementów i k
jest liczbą elementów, których potrzebujesz (5000 w Twoim przypadku).
Można to zrobić również w O(n)
za pomocą algorytmu wyboru - zapisz wszystkie elementy, a następnie znajdź 5001-ty największy element i zwróć wszystko większe od niego. Ale to jest trudniejsze do wdrożenia i dla rozsądnej wielkości Wejścia-może nie być lepiej. Ponadto, jeśli stream zawiera duplikaty, potrzebne jest więcej przetwarzania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-13 16:43:59
Użyj (minimalnej) kolejki priorytetów. Dodaj każdy przychodzący element do kolejki i gdy rozmiar osiągnie 5000 Usuń minimalny (górny) element za każdym razem, gdy dodasz przychodzący element. Kolejka będzie zawierać 5000 największych elementów, a gdy wejście się zatrzyma, po prostu usuń zawartość. Ten MinPQ jest również nazywany stertą, ale jest to termin przeciążony. Wstawianie i usuwanie zajmuje około log2(N). Gdzie n ma wartość 5000, to byłoby nieco ponad 12 [log2(4096) = 12] razy więcej pozycji niż przetwarzam.
Doskonałym źródłem informacji są algorytmy, (IV edycja) autorstwa Roberta Sedgewicka i Kevina Wayne ' a. Jest doskonałe MOOC na coursera.org na podstawie tego tekstu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-01 16:31:03