2017-11-09 11 views
4

Ich habe einen rekursiven Algorithmus mit zwei verschachtelten For-Schleifen. Ich versuche herauszufinden, wie groß die Komplexität von Big-O sein wird.Big-O-Zeit Komplexität des rekursiven Algorithmus mit verschachtelten For-Schleifen

public Set<Person> getDistinctCombinedPersons(Collection<Person> persons) { 
    return permutatePersons(new ArrayList(persons), new HashSet<>(persons)); 
} 

private Set<Person> permutatePersons(List<Person> personList, Set<Person> personSet) { 
    if(personList.isEmpty() { 
    return personSet; 
    } 

    Set<Person> deepCopyPersonSet = new HashSet<>(personSet); 

    for(Person lPerson : personList) { 
    for(Person sPerson : deepCopyPersonSet) { 
     Person uniquePerson = CombinePeople.combine(lPerson, sPerson); 
     personSet.add(uniquePerson); 
    } 
    } 

    personList.remove(personList.size()-1); 

    return permutatePersons(personList, personSet); 
} 
+1

(By the way, „tiefe Kopie“ bedeutet nicht, was Sie denken, es tut.) – ruakh

+0

@ruakh ja sollte ich gerade gesagt haben Klon – Grammin

+0

@ruakh Was ist Die Big-O-Komplexität meines Algorithmus – Grammin

Antwort

5

Unter der Annahme, dass Sie permutatePersons mit einer Liste der Länge N die folgende Rekursion gilt nennen:

Das ist, weil Sie in jedem rekursiven Schritt Funktion mit Liste der Länge N-1 aufrufen (wobei N der aktuelle Länge) und auch Berechnungen der Gesamtkomplexität O (N^2) (äußere Schleife O (N) -just traversierende Liste und innere Schleife durchlaufen die Hash-Karte in O (N) -O (1) für jedes Element und insgesamt N Element, also sind die verschachtelten Schleifen insgesamt O (N^2)). siehe

können Sie leicht:

T(N) = T(N-1) + O(N^2) = T(N-2) + O(N^2) + O((N-1)^2) =... 

= O(n(n+1)(2n+1)/6) = O(n^3) 
+0

Vielen Dank für die ausgezeichnete Antwort. Ich frage mich jetzt, ob ich die äußere for-Schleife raushole, ist der Algorithmus immer noch dasselbe? – Grammin

+0

In Bezug auf die Komplexität wird es in "O (N^2)" aufgrund der Rekursion nun reduziert sein: "T (N) = T (N - 1) + O (N)". – game0ver

+0

Ja, ich wundere mich zwar, wenn mein Algorithmus genau der gleiche ist, wenn ich die äußere for-Schleife einfach weniger komplex entferne – Grammin

0

sieht aus wie ein Big-O von n^2 für die verschachtelte Schleife sein würde:

for(Person lPerson : personList) { 
    for(Person sPerson : deepCopyPersonSet) { 
     Person uniquePerson = CombinePeople.combine(lPerson, sPerson); 
     personSet.add(uniquePerson); 
    } 
    } 

Sie müssen für jedes Element über die jedes Element iterieren in der Satz.

Und dann hat der rekursive Aufruf einen großen O von n, da er Ihre Methode einmal für jedes Element in der Menge aufruft.

Die Kombination der beiden: n * n^2 in einem großen O von n führen^3

+0

Welchen Effekt hat die Rekursion? – jhpratt

+0

@jhpratt Ich tue dies nicht die Methode verwendet Rekursion, es sei denn, ich vermisse etwas. Meinst du Iteration? – luckydog32

+0

Nein, die letzte Zeile ist ein rekursiver Aufruf. – jhpratt

0

Weil Sie zwei verschachtelte Schleifen haben haben Sie die Laufzeitkomplexität von O(m*n). Es ist, weil für n - Person s in deepCopyPersonSet Sie iterieren m mal. n In diesem Beispiel ist die Menge Person s in personList.

Ihr Code ist im Grunde:

for(int i = 0, i < m, i++) 
    for(int j = 0, j < n, j++) 
    //your code 

Für jede Iteration m, wir haben n Iterationen Code

+0

Ich habe auch den rekursiven Anruf dort auch – Grammin