Ich habe gerade ein Interview bombardiert und bei meiner Interviewfrage so gut wie keine Fortschritte gemacht. Kann mir jemand mitteilen, wie das geht? Ich habe versucht, online zu suchen, konnte aber nichts finden:
Suchen Sie bei gegebener Nummer die nächsthöhere Nummer, die genau die gleichen Ziffern wie die ursprüngliche Nummer hat. Zum Beispiel: gegeben 38276 return 38627
Ich wollte zunächst den Index der ersten Ziffer (von rechts) finden, der kleiner als die Ziffer war. Dann würde ich die letzten Ziffern in der Teilmenge so drehen, dass es die nächstgrößere Zahl war, die aus denselben Ziffern bestand, aber stecken blieb.
Der Interviewer schlug auch vor, die Ziffern einzeln auszutauschen, aber ich konnte den Algorithmus nicht herausfinden und starrte nur etwa 20 bis 30 Minuten lang auf einen Bildschirm. Unnötig zu sagen, ich denke, ich muss die Jobsuche fortsetzen.
edit: für was es wert ist, ich wurde zur nächsten Runde von Interviews eingeladen
next_permutation
;-)Antworten:
Sie können dies folgendermaßen tun
O(n)
(won
ist die Anzahl der Ziffern):Ausgehend von rechts finden Sie das erste Ziffernpaar so, dass die linke Ziffer kleiner als die rechte Ziffer ist. Beziehen wir uns auf die linke Ziffer mit "digit-x". Suchen Sie die kleinste Zahl größer als Ziffer-x rechts von Ziffer-x und platzieren Sie sie unmittelbar links von Ziffer-x. Sortieren Sie abschließend die verbleibenden Ziffern in aufsteigender Reihenfolge - da sie bereits in absteigender Reihenfolge waren, müssen Sie sie nur umkehren (außer für Ziffer-x, die an der richtigen Stelle in platziert werden kann
O(n)
) .Ein Beispiel wird dies deutlicher machen:
Korrektheitsnachweis:
Verwenden wir Großbuchstaben, um Ziffernfolgen und Kleinbuchstaben für Ziffern zu definieren. Die Syntax
AB
bedeutet "die Verkettung von ZeichenfolgenA
undB
" .<
ist die lexikografische Reihenfolge, die der ganzzahligen Reihenfolge entspricht, wenn die Ziffernfolgen gleich lang sind.Unsere ursprüngliche Nummer N hat die Form
AxB
, wobeix
es sich um eine einzelne ZifferB
handelt, die absteigend sortiert ist.Die Zahl gefunden von unserem Algorithmus ist
AyC
, woy ∈ B
ist die kleinste Ziffer> x
(es existieren muss aufgrund der Art und Weisex
oben gewählt wurde, sehen) , undC
wird sortiert aufsteigend.Angenommen, es gibt eine Zahl (mit denselben Ziffern),
N'
so dassAxB < N' < AyC
.N'
muss damit beginnenA
oder es könnte nicht zwischen sie fallen, damit wir es in der Form schreiben könnenAzD
. Jetzt ist unsere UngleichungAxB < AzD < AyC
gleichbedeutend damit,xB < zD < yC
dass alle drei Ziffernfolgen die gleichen Ziffern enthalten.Damit das wahr ist, müssen wir haben
x <= z <= y
. Day
ist die kleinste Ziffer> x
,z
kann nicht zwischen ihnen sein, also entwederz = x
oderz = y
. Sagen Siez = x
. Dann ist unsere UngleichungxB < xD < yC
, was bedeutet,B < D
wo beideB
undD
die gleichen Ziffern haben. Jedoch ist B Absteigen sortiert, so dass es ist keine Zeichenfolge mit diesen Ziffern größer , als es. Also können wir nicht habenB < D
. Wennz = y
wir die gleichen Schritte ausführen, sehen wir, dass wir es nicht haben könnenD < C
.Daher
N'
kann es nicht existieren, was bedeutet, dass unser Algorithmus die nächstgrößere Zahl korrekt findet.quelle
9 832
dann alles rechts von 9 sortieren:9238
Ein fast identisches Problem trat als Code Jam-Problem auf und hat hier eine Lösung:
http://code.google.com/codejam/contest/dashboard?c=186264#s=a&a=1
Hier ist eine Zusammenfassung der Methode anhand eines Beispiels:
A. Teilen Sie die Ziffernfolge in zwei Teile, damit der rechte Teil so lang wie möglich ist und in absteigender Reihenfolge bleibt:
(Wenn die gesamte Zahl in absteigender Reihenfolge vorliegt, kann keine größere Zahl ohne Hinzufügen von Ziffern erstellt werden.)
B.1. Wählen Sie die letzte Ziffer der ersten Sequenz:
B.2. Suchen Sie die kleinste Ziffer in der zweiten Sequenz, die größer ist als sie:
B.3. Tauschen Sie sie aus:
C. Sortieren Sie die zweite Sequenz in aufsteigender Reihenfolge:
D. Fertig!
quelle
Hier ist eine kompakte (aber teilweise Brute Force) Lösung in Python
In C ++ können Sie die Permutationen wie folgt vornehmen: https://stackoverflow.com/a/9243091/1149664 (Es ist der gleiche Algorithmus wie in itertools)
Hier ist eine Implementierung der von Weeble und BlueRaja beschriebenen Top-Antwort (andere Antworten). Ich bezweifle, dass es etwas Besseres gibt.
quelle
type 'map' has no len()
. Ich würde nur die 2. Zeile in änderniis=list(map(int,str(ii)))
. Und könnte jemandif i == 0: return ii
bitte die Zeile erklären ? Warum sollte es mit Eingaben wie 111 oder 531 funktionieren? Vielen Dank.i == len(iis)
.Hier sind mindestens ein paar Beispiele für Brute-Force-String-basierte Lösungen, die Sie sich auf Anhieb hätten einfallen lassen müssen:
Die Liste der Ziffern in
38276
sortiert ist23678
Die Liste der Ziffern in
38627
sortiert ist23678
Brute-Force-Inkrementierung, Sortierung und Vergleich
Entlang der Brute-Force-Lösung würden alle möglichen Zahlen unter Verwendung dieser Ziffern in einen String konvertiert und Brute-Force-Lösungen erzwungen.
Erstellen Sie Ints aus allen, fügen Sie sie in eine Liste ein und sortieren Sie sie. Erhalten Sie den nächsten Eintrag nach dem Zieleintrag.
Wenn Sie 30 Minuten damit verbracht hätten und sich nicht mindestens einen Brute-Force-Ansatz ausgedacht hätten, würde ich Sie auch nicht einstellen.
In der Geschäftswelt ist eine Lösung, die unelegant, langsam und klobig ist, aber die Arbeit erledigt, immer wertvoller als gar keine Lösung. Tatsächlich beschreibt sie so ziemlich jede Geschäftssoftware, unelegant, langsam und klobig.
quelle
quelle
Deine Idee
ist eigentlich ziemlich gut. Sie müssen nur nicht nur die letzte Ziffer berücksichtigen, sondern alle Ziffern von geringerer Bedeutung als die aktuell berücksichtigte. Da wir vorher eine monotone Folge von Ziffern haben, ist dies die am weitesten rechts stehende Ziffer, die kleiner ist als ihr rechter Nachbar. Betrachten
Die nächstgrößere Zahl mit den gleichen Ziffern ist
Die gefundene Ziffer wird gegen die letzte Ziffer ausgetauscht - die kleinste der betrachteten Ziffern - und die verbleibenden Ziffern werden in aufsteigender Reihenfolge angeordnet.
quelle
Ich bin mir ziemlich sicher, dass Ihr Interviewer versucht hat, Sie sanft zu so etwas zu drängen:
Nicht unbedingt die effizienteste oder eleganteste Lösung, aber sie löst das bereitgestellte Beispiel in zwei Zyklen und tauscht die Ziffern nacheinander aus, wie er vorgeschlagen hat.
quelle
Nehmen Sie eine Zahl und teilen Sie sie in Ziffern auf. Wenn wir also eine 5-stellige Nummer haben, haben wir 5 Ziffern: abcde
Tauschen Sie nun d und e aus und vergleichen Sie sie mit der ursprünglichen Nummer. Wenn diese größer ist, haben Sie Ihre Antwort.
Wenn es nicht größer ist, tauschen Sie e und c. Vergleichen Sie nun und wenn es kleiner ist, tauschen Sie d und e erneut aus (beachten Sie die Rekursion), nehmen Sie die kleinste.
Fahren Sie fort, bis Sie eine größere Anzahl finden. Bei der Rekursion sollten sich ungefähr 9 Schemazeilen oder 20 von c # ergeben.
quelle
Das ist eine sehr interessante Frage.
Hier ist meine Java-Version. Ich brauche ungefähr 3 Stunden, um das Muster vollständig fertigzustellen, bevor ich die Kommentare anderer Mitwirkender überprüft habe. Ich bin froh zu sehen, dass meine Idee mit anderen ganz gleich ist.
O (n) Lösung. Ehrlich gesagt, ich werde dieses Interview nicht bestehen, wenn die Zeit nur 15 Minuten beträgt und eine vollständige Code-Fertigstellung auf der weißen Tafel erforderlich ist.
Hier sind einige interessante Punkte für meine Lösung:
Ich habe in meinen Code einen detaillierten Kommentar und in jedem Schritt das große O eingefügt.
Hier ist das Ergebnis, das in Intellj ausgeführt wird:
quelle
Eine Javascript-Implementierung des @ BlueRaja-Algorithmus.
quelle
Eine Lösung (in Java) könnte die folgende sein (ich bin sicher, dass Freunde hier eine bessere finden können):
Tauschen Sie die Ziffern am Ende der Zeichenfolge aus, bis Sie eine höhere Zahl erhalten.
Dh zuerst die niedrigere Ziffer nach oben bewegen. Dann die nächsthöhere usw., bis Sie die nächsthöhere treffen.
Dann sortieren Sie den Rest. In Ihrem Beispiel würden Sie erhalten:
quelle
63872
Warum sollte es sein?Wenn Sie in C ++ programmieren, können Sie Folgendes verwenden
next_permutation
:quelle
100
? :-)Ich wusste nichts über den Brute-Force-Algorithmus, als ich diese Frage beantwortete, also näherte ich mich ihm aus einem anderen Blickwinkel. Ich habe mich entschlossen, die gesamte Palette möglicher Lösungen zu durchsuchen, in die diese Nummer möglicherweise umgeordnet werden könnte, angefangen von number_given + 1 bis zur maximal verfügbaren Nummer (999 für eine dreistellige Nummer, 9999 für 4 Ziffern usw.). Ich habe so etwas wie ein Palindrom mit Wörtern gefunden, indem ich die Zahlen jeder Lösung sortiert und mit der als Parameter angegebenen sortierten Zahl verglichen habe. Ich habe dann einfach die erste Lösung im Array der Lösungen zurückgegeben, da dies der nächstmögliche Wert wäre.
Hier ist mein Code in Ruby:
quelle
PHP-Code
quelle
Ich habe das nur mit zwei Zahlen getestet. Sie arbeiteten. Als IT-Manager für 8 Jahre bis zu meiner Pensionierung im vergangenen Dezember habe ich mich um drei Dinge gekümmert: 1) Genauigkeit: Es ist gut, wenn es funktioniert - immer. 2) Geschwindigkeit: muss für den Benutzer akzeptabel sein. 3) Klarheit: Ich bin wahrscheinlich nicht so schlau wie du, aber ich bezahle dich. Stellen Sie sicher, dass Sie auf Englisch erklären, was Sie tun.
Omar, viel Glück für die Zukunft.
quelle
Eine ausführliche Beschreibung dazu finden Sie unter " Algorithmus L " in Knuths " Die Kunst der Computerprogrammierung: Generieren aller Permutationen " (.ps.gz).
quelle
Hier ist mein Code, es ist eine modifizierte Version dieses Beispiels
Bibliothek:
Prüfung:
quelle
Addiere 9 zu der angegebenen n-stelligen Nummer. Überprüfen Sie dann, ob es innerhalb des Grenzwerts liegt (die erste (n + 1) Ziffernzahl). Wenn dies der Fall ist, prüfen Sie, ob die Ziffern in der neuen Nummer mit den Ziffern in der ursprünglichen Nummer übereinstimmen. Wiederholen Sie das Hinzufügen von 9, bis beide Bedingungen erfüllt sind. Stoppen Sie den Algo, wenn die Anzahl das Limit überschreitet.
Ich konnte keinen widersprüchlichen Testfall für diese Methode finden.
quelle
Nur eine andere Lösung mit Python:
Ausgabe:
quelle
quelle
Unten ist der Code, um alle Permutationen einer Zahl zu generieren. Allerdings muss man diese Ganzzahl zuerst mit String.valueOf (Ganzzahl) in einen String konvertieren.
quelle
quelle
Eine weitere Java-Implementierung, die sofort ausgeführt werden kann und mit Tests abgeschlossen wurde. Diese Lösung ist O (n) Raum und Zeit unter Verwendung einer guten alten dynamischen Programmierung.
Wenn man Bruteforce betreiben möchte, gibt es zwei Arten von Bruteforce:
Erlaube alle Dinge und wähle dann min höher: O (n!)
Ähnlich wie bei dieser Implementierung, jedoch anstelle von DP, wird das Bruteforcen des Schritts zum Auffüllen der indexToIndexOfNextSmallerLeft-Map in O (n ^ 2) ausgeführt.
quelle
Wir müssen das am weitesten rechts stehende Bit 0 gefolgt von einer 1 finden und dieses am weitesten rechts stehende 0-Bit auf eine 1 drehen.
Nehmen wir zum Beispiel an, unsere Eingabe ist 487, was 111100111 in Binärform ist.
Wir drehen die 0 ganz rechts um, auf die 1 folgt
so bekommen wir 111101111
Aber jetzt haben wir eine zusätzliche 1 und eine weniger 0, also reduzieren wir die Anzahl der Einsen rechts vom Flip-Bit um 1 und erhöhen die Anzahl der 0-Bits um 1, was ergibt
111101011 - binär 491
quelle
quelle
Hier ist die Java-Implementierung
Hier sind die Unit Tests
quelle
Ich weiß, dass dies eine sehr alte Frage ist, aber ich habe in c # immer noch keinen einfachen Code gefunden. Dies könnte Leuten helfen, die an Interviews teilnehmen.
quelle
Sehr einfache Implementierung mit Javascript, nächsthöhere Zahl mit gleichen Ziffern
Da es viele Kommentare gibt, ist es besser, sie in Ihren Texteditor zu kopieren. Vielen Dank!
quelle
Es gibt viele gute Antworten, aber ich habe keine anständige Java-Implementierung gefunden. Hier sind meine zwei Cent:
quelle
quelle