Wie können Sie bei zwei gegebenen Zeichenfolgen überprüfen, ob sie eine Permutation voneinander sind, indem Sie den O (1) -Raum verwenden? Das Ändern der Zeichenfolgen ist in keiner Weise zulässig.
Anmerkung: O (1) Abstand in Bezug sowohl auf die Zeichenkettenlänge als auch auf die Größe des Alphabets.
algorithms
strings
space-complexity
Anonym
quelle
quelle
O(log n)
für Zeichenfolgen der Länge n gespeichert, die weder über die Länge noch über die Alphabetgröße konstant ist. Wenn die Zeichenfolgen vorübergehend geändert werden können, gibt es meines Erachtens eine Lösung mit vergrößertem Alphabet, das in der Alphabetgröße linear ist, in einem logarithmischen Modell jedoch eine konstante Zeichenfolgenlänge aufweist.Antworten:
Der naive Ansatz würde darin bestehen, Histogramme beider Zeichenfolgen zu erstellen und zu überprüfen, ob sie gleich sind. Da wir keine Datenstruktur speichern dürfen (deren Größe linear zur Größe des Alphabets wäre), die in einem Durchgang berechnet werden könnte, müssen wir die Vorkommen der einzelnen möglichen Symbole nacheinander zählen:
Dies setzt natürlich voraus, dass die Zählwerte und Iteratorindizes ganze Zahlen konstanter Größe sind, anstatt von der Länge der Zeichenfolgen abhängig zu sein.
quelle
O(n * min(n, |Σ|))
. Hm, jetzt, wo ich darüber nachdenke, hört sich das nach der "darf wiederholen" -Lösung aus Ihrer Antwort an, nicht wahr?count
ist nichtO(1)
(dh es kann überlaufen)count
das ein warint
:-) Ja, es würde nicht funktionieren, aber in Java kann das sowieso nicht passierenBezeichnen Sie die Arrays mit und nehmen Sie an, dass sie die Länge n haben .A , B n
Nehmen wir zunächst an, dass die Werte in jedem Array unterschiedlich sind. Hier ist ein Algorithmus, der den -Raum verwendet:O ( 1 )
Berechnen Sie die Mindestwerte beider Arrays und überprüfen Sie, ob sie identisch sind.
Berechnen Sie die zweiten Mindestwerte beider Arrays und überprüfen Sie, ob sie identisch sind.
Und so weiter.
Bei der Berechnung des Mindestwerts eines Arrays wird eindeutig der Abstand verwendet. Ausgehend von dem k- ten kleinsten Element können wir ( k + 1 findenO ( 1 ) k indemden Minimalwert finden, der größer als das k- te kleinste Element ist (hier verwenden wir die Tatsache, dass alle Elemente verschieden sind).( k + 1 ) k
Wenn sich Elemente wiederholen dürfen, ändern wir den Algorithmus wie folgt:
Berechnen Sie die Mindestwerte beider Arrays, zählen Sie, wie oft sie jeweils auftreten, und überprüfen Sie, ob m A , 1 = m B istmA , 1, mB , 1 und dass die Zählungen identisch sind.mA , 1= mB , 1
Berechnen Sie die Mindestwerte größer als m A , 1 , m B , 1 in den beiden Arrays sind, und zählen Sie, wie oft sie jeweils auftreten. Stellen Sie sicher, dass m A , 2 = m B , 2 ist und dass die Zählungen identisch sind.mA , 2, mB , 2 mA , 1, mB , 1 mA , 2= mB , 2
Und so weiter.
quelle
Definieren Sie eine Funktion f (c), die ein Zeichen c einer eindeutigen Primzahl zuordnet (a = 2, b = 3, c = 5 usw.).
Nur zu erklären, dass Sie eine Primzahlzuordnungsfunktion verwenden können, ist ein bisschen handwavey, und am wahrscheinlichsten, wenn ein Problem auftreten würde, Raum zu halten.O (1)
quelle
Sie können dies tunO(nlogn)
. Sortieren Sie die beiden Zeichenfolgen und vergleichen Sie sie indexweise. Wenn sie sich irgendwo unterscheiden, sind sie keine Permutationen voneinander.Für eine
O(n)
Lösung könnte Hashing verwendet werden. Diese Hash-Funktion würde funktionieren, unde
für jeden Buchstaben wäre dies der ASCII-Wert. Wenn sich die beiden Hashes der Zeichenfolgen unterscheiden, sind sie keine Permutationen voneinander.Die Hash-Funktion im Link:
Durch die Verwendung von Double-Hashing (oder für noch mehr Overkill) durch Ändern des Werts von R würden sie erfolgreich als Permutationen mit sehr hoher Wahrscheinlichkeit identifiziert .
quelle
Angenommen, Sie haben zwei Zeichenfolgen mit den Namen s und t.
Sie können Heuristiken verwenden, um sicherzustellen, dass sie nicht ungleich sind.
Danach können Sie leicht einen Algorithmus ausführen, um zu beweisen, dass die Zeichenfolge gleich ist.
Natürlich können Sie nicht so schnell sortieren, wenn Sie keinen zusätzlichen Speicherplatz verwenden dürfen. Es spielt also keine Rolle, welchen Algorithmus Sie wählen - jeder benötigte Algorithmus wird in O (n ^ 2) ausgeführt, wenn nur O (1) Platz vorhanden ist und die Heuristik nicht beweisen konnte, dass sie nicht gleich sein können.
quelle
Im C-Code für die gesamte Routine:
Oder in sehr ausführlichem Pseudocode (mit 1-basierter Indizierung)
Dabei prüft die Funktion checkLetters (A, B, i), ob in A [1] .. A [i] M Kopien von A [i] vorhanden sind. In B sind dann mindestens M Kopien von A [i] vorhanden:
Die Funktion findNextValue sucht in B nach einem Wert, der von einem Index ausgeht, und gibt den Index an der Stelle zurück, an der er gefunden wurde (oder n + 1, wenn er nicht gefunden wurde).
Die Idee hier ist, dass wir bereits bestätigt haben, dass wir eine Permutation der Zeichen vor i in der äußeren Schleife haben. In der j-Schleife durchlaufen wir alle Zeichen, die mit A [i] übereinstimmen, und müssen in der Lage sein, eindeutige Indizes in B zu finden, die mit ihnen übereinstimmen (einschließlich der i-ten Position). Daher müssen wir für jeden von ihnen unseren Scan um B vorwärts bewegen. Die Zeit ist O (n2 ).
quelle
Ich denke das ist der einfachste Algorithmus (mitO ( n3 ) Zeit, n Länge der Saiten)
Durchlaufe
string1
undstring2
, überprüfe für jeden Charakter, wie oft er instring1
und zu finden iststring2
. Wenn ein Zeichen in einer Zeichenfolge häufiger vorkommt als in der anderen, handelt es sich nicht um eine Permutation. Wenn die Frequenzen aller Zeichen gleich sind, sind die Zeichenfolgen Permutationen voneinander.Hier ist ein Stück Python, um dies zu präzisieren
Das Programm benötigt einige Hinweise auf Strings (O ( logn ) zum Zählen (
string
,string1
,string2
,char
,char1
,char2
) und Variablen der Größecount1
,count2
). Es muss überprüft werden, ob die Zeichen gleich sind oder nicht, aber es muss keine Reihenfolge für diese Zeichen festgelegt werden. Vielleicht braucht es einige Variablen für kleine ganze Zahlen (zB um boolesche Werte zu speichern oder die Position vonstring
in darzustellen[string1, string2]
.Natürlich brauchen Sie nicht einmal die Zählvariablen, sondern können Zeiger verwenden.
Dieses zweite Programm benötigt ähnliche Variablen wie das erste, außer dass es das nicht benötigtO ( log( n ) ) -size Variablen zum Speichern der Zählwerte.
Also kommt es eigentlich nicht darauf ann oder die Größe des Alphabets.
quelle