Les verres d'eau vides sont disposés dans l'ordre suivant:
Lorsque vous versez du liquide dans le premier verre s'il est plein, le liquide supplémentaire sera envoyé dans les verres 2 et 3 en quantités égales. Lorsque le verre 2 est plein, le liquide supplémentaire serait transporté en 4 et 5 et ainsi de suite.
Étant donné un N litres de liquide et la capacité maximale de chaque verre est de 1 litre, donnez la quantité de liquide présente dans n'importe quel verre si vous videz N litres de liquide en versant dans du verre en remplissant la fonction getWaterInBucket(int N, int X)
où X est le numéro du verre. Donc par exemple si je veux avoir 4 litres au début et que je veux trouver l'eau dans le verre 3 la fonction estgetWaterInBucket(4, 3)
Comment résoudre ce problème par programme? J'ai essayé de trouver une solution mathématique en utilisant le triangle de Pascal. Cela n'a pas fonctionné. Je l'ai considéré comme un arbre, je peux donc ajouter un paramètre comme celui-ci getWaterInBucket(BTree root, int N, int X)
, puis essayer une solution récursive pour chaque niveau, mais les paramètres ne sont pas autorisés dans ce problème. Y a-t-il quelque chose d'évident, une astuce?
la source
Réponses:
Vous avez juste besoin de simuler la coulée, quelque chose comme
En l'état, ce n'est pas un arbre. Parce que différents verres se déversent dans les mêmes verres, cela l'empêche d'être un arbre.
la source
return glasses[N-1]
, parce que les numéros de verre commencent à 1 au lieu de 0.Voici comment je répondrais à cette question dans une situation d'entrevue (je n'ai jamais vu cette question auparavant, et je n'ai pas regardé les autres réponses avant d'avoir ma solution):
Tout d'abord, j'ai essayé de le comprendre (que vous avez appelé la "solution mathématique") et quand je suis arrivé au verre 8, j'ai réalisé que ce serait plus difficile qu'il n'y paraissait parce que le verre 5 commence à déborder avant le verre 4. À ce stade, j'ai a décidé d'emprunter la voie de la récursivité (juste un FYI, beaucoup de questions d'entrevue de programmation nécessitent une récursivité ou une induction pour résoudre).
En pensant récursivement, le problème devient beaucoup plus facile: combien d'eau est dans le verre 8? La moitié de la quantité qui a débordé des verres 4 et 5 (jusqu'à ce qu'elle soit pleine). Bien sûr, cela signifie que nous devons répondre aux débordements des verres 4 et 5, mais il s'avère que ce n'est pas trop difficile non plus. Combien a coulé du verre 5? Cependant, la moitié de la quantité de liquide renversée dans les verres 2 et 3, moins le litre restant dans le verre 5.
Résoudre cela complètement (et malproprement) donne:
À ce stade (ou au moment où j'écrivais ceci), je dirais à l'intervieweur que ce n'est pas la solution idéale en production: il y a du code en double entre
howMuchSpilledOutOf()
etgetWaterInBucket()
; il devrait y avoir un emplacement central qui mappe les compartiments à leurs «alimenteurs». Mais dans une interview, où la vitesse et la précision de la mise en œuvre sont plus importantes que la vitesse d'exécution et la maintenabilité (sauf indication contraire), cette solution est préférable. Ensuite, je proposerais de refactoriser le code pour qu'il soit plus proche de ce que je considère comme une qualité de production, et laisser l'intervieweur décider.Remarque finale: je suis sûr que mon code contient une faute de frappe quelque part; Je le mentionnerais aussi à l'intervieweur et je lui dirais que je me sentirais plus en confiance après l'avoir refactorisé ou testé à l'unité.
la source
this isn't the ideal solution
.Penser à cela comme un problème d'arbre est un redingue, c'est vraiment un graphique dirigé. Mais oubliez tout ça.
Pensez à un verre n'importe où sous celui du haut. Il aura un ou deux verres au-dessus qui peuvent déborder. Avec le choix approprié du système de coordonnées (ne vous inquiétez pas, voir la fin), nous pouvons écrire une fonction pour obtenir les verres "parents" pour n'importe quel verre donné.
Maintenant, nous pouvons penser à un algorithme pour obtenir la quantité de liquide versée dans un verre, indépendamment du débordement de ce verre. La réponse est cependant que beaucoup de liquide est versé dans chaque parent moins la quantité stockée dans chaque verre parent, divisée par 2. Additionnez cela pour tous les parents. L'écriture en tant que fragment python du corps d'une fonction amount_poured_into ():
Le max () est de s'assurer que nous n'obtenons pas une quantité négative de débordement.
Nous avons presque fini! Nous choisissons un système de coordonnées avec «y» en bas de la page, les verres de la première rangée sont 0, la deuxième rangée est 1, etc. Les coordonnées «x» ont un zéro sous le verre de la rangée supérieure et la deuxième rangée a les coordonnées x de -1 et +1, troisième ligne -2, 0, +2, etc. Le point important est que le verre le plus à gauche ou à droite du niveau y aura abs (x) = y.
Enveloppant tout cela en python (2.x), nous avons:
Donc, pour obtenir la quantité réellement dans un verre à p, utilisez amount_in (total, p).
Ce n'est pas clair à partir de l'OP, mais le peu de "vous ne pouvez pas ajouter de paramètres" peut signifier que la question d'origine doit être répondue en termes de numéros de verre affichés. Ceci est résolu en écrivant une fonction de mappage des numéros de verre d'exposition au système de coordonnées interne utilisé ci-dessus. C'est compliqué, mais une solution itérative ou mathématique peut être utilisée. Une fonction itérative facile à comprendre:
Maintenant, réécrivez simplement la fonction amount_in () ci-dessus pour accepter un numéro de verre:
la source
Intéressant.
Cela prend l'approche de simulation.
qui imprime (pour 6 litres):
qui semble être à peu près juste.
la source
Ceci est la fonction binomiale. Le rapport de l'eau entre les verres de niveau N peut être découvert en utilisant nCr pour chaque verre du niveau. De plus, le nombre total de verres avant le niveau N est la somme de 1 à (N - 1), une formule pour laquelle vous devriez pouvoir trouver les produits disponibles assez facilement. Ainsi, étant donné X, vous devriez pouvoir déterminer son niveau et utiliser nCr pour vérifier les rapports des verres pour ce niveau, et ainsi déterminer la quantité d'eau dans X, s'il y a suffisamment de litres pour descendre jusqu'à X de toute façon.
Deuxièmement, votre idée d'utiliser le BTree est très bien, c'est juste que le BTree est une variable interne, pas un paramètre externe.
IOW, si vous avez couvert ces mathématiques dans votre éducation (ici au Royaume-Uni, elles sont enseignées avant l'université), vous devriez être en mesure de résoudre ce problème sans trop de problèmes.
la source