Comment résoudre la question d’entretien Python « Gas Station » efficacement?
Introduction
Dans cet article, nous allons explorer en détail la question d’entretien souvent posée pour les développeurs Python : le problème de la « Gas Station ». Ce type de problème est un classique dans les entretiens techniques, car il teste non seulement vos compétences en algorithmie, mais aussi votre capacité à optimiser des solutions en termes de complexité temporelle et spatiale.
Définition du problème
Le problème consiste à déterminer si une voiture peut effectuer un tour complet autour d’un circuit de stations-service. Il vous est fourni deux listes : gas
et cost
. La première liste indique la quantité de gaz disponible à chaque station, tandis que la deuxième liste indique le coût en gaz nécessaire pour voyager jusqu’à la station suivante. L’objectif est de déterminer le point de départ minimal à partir duquel un tour complet est possible, ou de retourner -1 si cela est impossible.
Objectifs de l’article
L’objectif de cet article est de fournir une compréhension claire et approfondie du problème, ainsi que de présenter des stratégies de résolution efficaces. Nous explorerons d’abord une solution brute-force, puis une approche optimisée pour atteindre des résultats plus performants.
Comprendre le problème
Pour bien appréhender le problème, imaginons un scénario de station-service où nous avons les éléments suivants :
gas = [1, 2, 3, 4, 5]
cost = [3, 4, 5, 1, 2]
Dans ce cas, il est possible de commencer à partir de la station 3 et effectuer un tour complet, car l’essence totale est suffisante pour couvrir les coûts.
Contraintes et conditions
Avant de plonger dans les solutions, il est crucial de comprendre les contraintes du problème :
- Si la somme totale de
gas
est inférieure à la somme totale decost
, un tour complet est impossible, et nous devrons retourner -1. - L’objectif est de trouver le point de départ le plus bas pour un tour complet.
Analyse du problème
Pour une compréhension approfondie, analysons quelques exemples simples.
Exploration des exemples
Considérons un exemple où :
– gas = [2, 3, 4]
– cost = [3, 4, 3]
Dans ce cas, la somme totale de gas
(9) excède celle de cost
(10). Aucune station ne permettra un tour complet, donc le retour sera -1.
Identification des cas de bord
Un cas de bord pourrait être lorsque toutes les stations ont exactement le même gaz et coût, par exemple gas = [5, 5, 5]
et cost = [5, 5, 5]
. Ici, le tour peut commencer à n’importe quelle station.
Approches de résolution
Approche naïve
L’approche brute-force consiste à essayer chaque station comme point de départ potentiel. Pour chacune, nous vérifions si un tour complet est réalisable.
Exemple de code
def can_complete_circuit_naive(gas, cost):
n = len(gas)
for start in range(n):
fuel = 0
valid_start = True
for i in range(n):
index = (start + i) % n
fuel += gas[index] - cost[index]
if fuel < 0:
valid_start = False
break
if valid_start:
return start
return -1
Analyse de la complexité
La complexité temporelle de cette approche est O(n^2), puisqu’on évalue chaque station en tant que point de départ potentiel et effectue un cycle à chaque fois.
Approche optimisée
Une approche inspirée de la méthode de Kadane pour la station-service est plus efficace. L’idée est de parcourir une seule fois la liste en utilisant les différences entre gas
et cost
.
Explication pas à pas de l’algorithme
- Créez une variable
total_gas
,total_cost
, ettank
pour suivre le gaz disponible. - Parcourez chaque station, mettez à jour
total_gas
,total_cost
ettank
. - Si
tank
devient négatif, cela signifie que le voyage n’est pas possible à partir du point de départ actuel ; réinitialisez et définissez le prochain point de départ comme le suivant. - Si, après tout les oscillations,
total_gas
est plus grand ou égal àtotal_cost
, le point de départ retenu est valide.
Exemple de code optimisé
def can_complete_circuit_optimized(gas, cost):
total_gas = total_cost = tank = 0
start = 0
for i in range(len(gas)):
total_gas += gas[i]
total_cost += cost[i]
tank += gas[i] - cost[i]
if tank < 0:
start = i + 1
tank = 0
return start if total_gas >= total_cost else -1
Comparaison
Cette approche optimise la complexité en la réduisant à O(n), car elle ne passe qu’une fois à travers les listes gas
et cost
.
Implémentation en Python
Maintenant, implémentons cette solution en Python avec des commentaires explicatifs.
def can_complete_circuit_optimized(gas, cost):
total_gas = total_cost = tank = 0
start = 0
# Parcourt toutes les stations
for i in range(len(gas)):
total_gas += gas[i]
total_cost += cost[i]
tank += gas[i] - cost[i]
if tank < 0: # S'il n'y a pas assez de gaz pour continuer
start = i + 1 # Change le point de départ
tank = 0 # Réinitialise le réservoir
# Vérifie si le gaz total est suffisant
return start if total_gas >= total_cost else -1
# Cas de tests
print(can_complete_circuit_optimized([1,2,3,4,5], [3,4,5,1,2])) # Output: 3
print(can_complete_circuit_optimized([2,3,4], [3,4,3])) # Output: -1
Cas de tests
- Vérifions la solution avec l’exemple ci-dessus et plusieurs autres, y compris les cas de bord, pour garantir sa robustesse.
Conseils pour réussir l’entretien
Voici quelques conseils pour aborder ce type de question efficacement :
Meilleures pratiques de codage
- Assurez-vous que votre code est lisible et bien commenté.
- Écrivez des tests unitaires pour valider vos solutions.
Stratégies de présentation
- Expliquez clairement votre démarche et justifiez vos choix algorithmiques.
- Comparez votre solution optimisée à la méthode naïve pour montrer les gains en termes de performance.
Conclusion
Le problème de la « Gas Station » est un excellent exercice pour développer des compétences en résolution de problèmes et en optimisation. N’oubliez pas de pratiquer régulièrement des questions similaires pour renforcer votre compréhension des structures algorithmiques.
Annexes
- LeetCode – Gas Station
- HackerRank – Algorithm Practice
- Explorez d’autres problèmes classiques d’entretien comme « Two Sum » et « Longest Substring Without Repeating Characters ».