Je viens de bombarder une interview et de n'avoir fait pratiquement aucun progrès sur ma question d'entrevue. Quelqu'un peut-il me dire comment procéder? J'ai essayé de chercher en ligne mais je n'ai rien trouvé:
Étant donné un nombre, recherchez le nombre immédiatement supérieur qui a exactement le même ensemble de chiffres que le numéro d'origine. Par exemple: étant donné 38276, renvoyer 38627
Je voulais commencer par trouver l'indice du premier chiffre (à partir de la droite) qui était inférieur à celui des chiffres. Ensuite, je faisais pivoter les derniers chiffres du sous-ensemble de sorte que ce soit le deuxième plus grand nombre composé des mêmes chiffres, mais je suis resté bloqué.
L'intervieweur a également suggéré d'essayer de permuter les chiffres un à la fois, mais je n'ai pas pu comprendre l'algorithme et j'ai juste regardé un écran pendant 20 à 30 minutes. Inutile de dire que je pense que je vais devoir continuer la recherche d'emploi.
edit: pour ce que ça vaut, j'ai été invité à la prochaine série d'entretiens
next_permutation
;-)Réponses:
Vous pouvez le faire en
O(n)
(oùn
est le nombre de chiffres) comme ceci:En partant de la droite, vous trouvez la première paire de chiffres telle que le chiffre de gauche est plus petit que le chiffre de droite. Faisons référence au chiffre de gauche par "digit-x". Trouvez le plus petit nombre supérieur à digit-x à droite de digit-x et placez-le immédiatement à gauche de digit-x. Enfin, triez les chiffres restants dans l'ordre croissant - car ils étaient déjà dans l' ordre décroissant , tout ce que vous avez à faire est de les inverser (sauf pour digit-x, qui peut être placé au bon endroit dans
O(n)
) .Un exemple rendra cela plus clair:
Preuve de correction:
Utilisons les majuscules pour définir les chaînes de chiffres et les minuscules pour les chiffres. La syntaxe
AB
signifie "la concaténation des chaînesA
etB
" .<
est un ordre lexicographique, qui est identique à un ordre entier lorsque les chaînes de chiffres sont de longueur égale.Notre numéro d'origine N est de la forme
AxB
, oùx
est un seul chiffre etB
est trié décroissant.Le nombre trouvé par notre algorithme est
AyC
, oùy ∈ B
est le plus petit chiffre> x
(il doit exister en raison de la manièrex
choisie, voir ci-dessus) , etC
est trié croissant.Supposons qu'il existe un certain nombre (en utilisant les mêmes chiffres)
N'
tel queAxB < N' < AyC
.N'
doit commencer parA
ou sinon il ne pourrait pas tomber entre eux, donc nous pouvons l'écrire dans le formulaireAzD
. Maintenant, notre inégalité estAxB < AzD < AyC
, ce qui équivaut à l'xB < zD < yC
endroit où les trois chaînes de chiffres contiennent les mêmes chiffres.Pour que cela soit vrai, nous devons avoir
x <= z <= y
. Puisquey
c'est le plus petit chiffre> x
,z
ne peut pas être entre eux, donc soitz = x
ouz = y
. Disz = x
. Ensuite, notre inégalité estxB < xD < yC
, ce qui signifieB < D
où les deuxB
etD
ont les mêmes chiffres. Cependant, B est trié décroissant, il n'y a donc pas de chaîne avec ces chiffres plus grands que lui. Nous ne pouvons donc pas avoirB < D
. En suivant les mêmes étapes, nous voyons que siz = y
, nous ne pouvons pas avoirD < C
.Par conséquent,
N'
il ne peut pas exister, ce qui signifie que notre algorithme trouve correctement le prochain plus grand nombre.la source
9 832
puis triez tout à droite de 9:9238
Un problème presque identique est apparu comme un problème Code Jam et a une solution ici:
http://code.google.com/codejam/contest/dashboard?c=186264#s=a&a=1
Voici un résumé de la méthode à l'aide d'un exemple:
A. Divisez la séquence de chiffres en deux afin que la partie droite soit aussi longue que possible tout en restant dans l'ordre décroissant:
(Si le nombre entier est en ordre décroissant, il n'y a pas de plus grand nombre à faire sans ajouter de chiffres.)
B.1. Sélectionnez le dernier chiffre de la première séquence:
B.2. Trouvez le plus petit chiffre de la deuxième séquence qui est plus grand que lui:
B.3. Échangez-les:
C. Triez la deuxième séquence par ordre croissant:
D. Terminé!
la source
Voici une solution compacte (mais en partie brutale) en Python
En C ++, vous pouvez faire les permutations comme ceci: https://stackoverflow.com/a/9243091/1149664 (C'est le même algorithme que celui dans itertools)
Voici une implémentation de la première réponse décrite par Weeble et BlueRaja, (autres réponses). Je doute qu'il y ait quelque chose de mieux.
la source
type 'map' has no len()
. Je changerais simplement la 2e ligne eniis=list(map(int,str(ii)))
. Et quelqu'un pourrait-il expliquer laif i == 0: return ii
ligne s'il vous plaît? Pourquoi cela fonctionnerait-il avec des entrées telles que 111 ou 531? Merci.i == len(iis)
.Au minimum, voici quelques exemples de solutions basées sur des chaînes de force brute, que vous auriez dû être en mesure de trouver dès le départ:
la liste des chiffres
38276
triés est23678
la liste des chiffres
38627
triés est23678
incrémenter, trier et comparer la force brute
Le long de la force brute, les solutions seraient converties en une chaîne et en force brute tous les nombres possibles en utilisant ces chiffres.
Créez des entiers à partir de tous, mettez-les dans une liste et triez-les, obtenez l'entrée suivante après l'entrée cible.
Si vous avez passé 30 minutes sur ce sujet et n'avez pas au moins trouvé au moins une approche par force brute, je ne vous embaucherais pas non plus.
Dans le monde des affaires, une solution inélégante, lente et maladroite mais qui fait le travail a toujours plus de valeur qu'aucune solution, en fait, elle décrit à peu près tous les logiciels d'entreprise, inélégants, lents et maladroits.
la source
la source
Ton idée
est assez bon, en fait. Il vous suffit de prendre en compte non seulement le dernier chiffre, mais tous les chiffres de moindre importance que celui actuellement considéré. Depuis avant cela, nous avons une séquence monotone de chiffres, c'est-à-dire le chiffre le plus à droite plus petit que son voisin droit. Qui concerne
Le nombre supérieur suivant ayant les mêmes chiffres est
Le chiffre trouvé est échangé contre le dernier chiffre - le plus petit des chiffres considérés - et les chiffres restants sont classés par ordre croissant.
la source
Je suis assez sûr que votre intervieweur essayait de vous pousser doucement vers quelque chose comme ça:
Pas nécessairement la solution la plus efficace ou la plus élégante, mais elle résout l'exemple fourni en deux cycles et permute les chiffres un à la fois comme il l'a suggéré.
la source
Prenez un nombre et divisez-le en chiffres. Donc, si nous avons un nombre à 5 chiffres, nous avons 5 chiffres: abcde
Maintenant, échangez d et e et comparez avec le nombre d'origine, s'il est plus grand, vous avez votre réponse.
S'il n'est pas plus grand, échangez e et c. Maintenant, comparez et s'il est plus petit, échangez à nouveau d et e (remarquez la récursivité), prenez le plus petit.
Continuez jusqu'à ce que vous trouviez un plus grand nombre. Avec la récursivité, cela devrait fonctionner comme environ 9 lignes de schéma, ou 20 de c #.
la source
C'est une question très intéressante.
Voici ma version java. Prenez-moi environ 3 heures après avoir trouvé le modèle pour terminer complètement le code avant de vérifier les commentaires des autres contributeurs. Heureux de voir que mon idée est la même que celle des autres.
Solution O (n). Honnêtement, j'échouerai cette interview si le temps n'est que de 15 minutes et nécessite la fin du code complet sur tableau blanc.
Voici quelques points intéressants pour ma solution:
Je mets des commentaires détaillés dans mon code, et le Big O à chaque étape.
Voici le résultat en cours d'exécution dans Intellj:
la source
Une implémentation javascript de l'algorithme de @ BlueRaja.
la source
Une solution (en Java) pourrait être la suivante (je suis sûr que des amis ici peuvent trouver une meilleure solution):
Commencez à échanger des chiffres à partir de la fin de la chaîne jusqu'à ce que vous obteniez un nombre plus élevé.
C'est-à-dire commencer d'abord à monter le chiffre inférieur, puis le prochain supérieur, etc. jusqu'à ce que vous atteigniez le prochain supérieur.
Triez ensuite le reste. Dans votre exemple, vous obtiendrez:
la source
63872
.Pourquoi, que devrait-elle être?Si vous programmez en C ++, vous pouvez utiliser
next_permutation
:la source
100
? :-)Je ne savais rien de l'algorithme de force brute en répondant à cette question, alors je l'ai abordé sous un autre angle. J'ai décidé de rechercher toute la gamme de solutions possibles dans lesquelles ce nombre pourrait éventuellement être réorganisé, en commençant par number_given + 1 jusqu'au nombre maximum disponible (999 pour un nombre à 3 chiffres, 9999 pour 4 chiffres, etc.). J'ai fait ce genre de recherche d'un palindrome avec des mots, en triant les nombres de chaque solution et en les comparant au nombre trié donné comme paramètre. J'ai ensuite simplement renvoyé la première solution dans le tableau de solutions, car ce serait la prochaine valeur possible.
Voici mon code en Ruby:
la source
Code PHP
la source
Je n'ai testé cela qu'avec deux chiffres. Ils ont travaillé. En tant que responsable informatique pendant 8 ans jusqu'à ma retraite en décembre dernier, je me souciais de trois choses: 1) Précision: c'est bien si cela fonctionne - toujours. 2) Vitesse: doit être acceptable pour l'utilisateur. 3) Clarté: je ne suis probablement pas aussi intelligent que vous, mais je vous paie. Assurez-vous d'expliquer ce que vous faites, en anglais.
Omar, bonne chance pour l'avenir.
la source
Pour une belle description de la façon de procéder, voir « Algorithme L » dans « L'art de la programmation informatique: générer toutes les permutations » de Knuth (.ps.gz).
la source
Voici mon code, c'est une version modifiée de cet exemple
Bibliothèque:
Tester:
la source
Ajoutez 9 au nombre de n chiffres donné. Vérifiez ensuite s'il se trouve dans la limite (le premier (n + 1) chiffre). Si c'est le cas, vérifiez si les chiffres du nouveau numéro sont identiques à ceux du numéro d'origine. Répétez l'ajout de 9 jusqu'à ce que les deux conditions soient remplies. Arrêtez l'algo lorsque le nombre dépasse la limite.
Je n'ai pas pu trouver un cas de test contradictoire pour cette méthode.
la source
Juste une autre solution utilisant python:
Production:
la source
la source
Ci-dessous se trouve le code pour générer toutes les permutations d'un nombre .. bien qu'il faut d'abord convertir cet entier en chaîne en utilisant String.valueOf (entier).
la source
la source
Encore une autre implémentation Java, exécutable prête à l'emploi et complétée par des tests. Cette solution est O (n) espace et temps en utilisant une bonne vieille programmation dynamique.
Si l'on veut brutaliser, il existe 2 types de bruteforce:
Permutez toutes les choses, puis choisissez min plus haut: O (n!)
Similaire à cette implémentation, mais au lieu de DP, l'application brute de l'étape de remplissage de la carte indexToIndexOfNextSmallerLeft s'exécutera dans O (n ^ 2).
la source
Nous devons trouver le bit 0 le plus à droite suivi d'un 1 et retourner ce bit le plus à droite en 1.
par exemple, disons que notre entrée est 487, qui est 111100111 en binaire.
nous retournons le plus à droite 0 qui a 1 suivant
nous obtenons donc 111101111
mais maintenant nous avons un 1 supplémentaire et un 0 de moins, donc nous réduisons le nombre de 1 à droite du bit flip de 1 et augmentons le nombre de 0 bits de 1, ce qui donne
111101011 - binaire 491
la source
la source
Voici l'implémentation Java
Voici les tests unitaires
la source
Je sais que c'est une très vieille question mais je n'ai toujours pas trouvé de code facile en c #. Cela pourrait aider les gars qui assistent aux entretiens.
la source
Implémentation très simple en utilisant Javascript, numéro suivant avec les mêmes chiffres
Comme il y a beaucoup de commentaires, il est préférable de le copier dans votre éditeur de texte. Merci!
la source
Il y a beaucoup de bonnes réponses mais je n'ai pas trouvé d'implémentation Java décente. Voici mes deux cents:
la source
la source