Solution du problème Leetcode 55 : Jeu du Saut

Le problème 55 de Leetcode, appelé Jeu du Saut, consiste à vérifier si on peut atteindre le dernier index d'un tableau en partant du premier, où chaque élément indique la distance maximale de saut autorisée.

Plusieurs méthodes algorithmiques s'appliquent, incluant le backtracking, la programmation dynamique et l'approche greedy. Le backtracking explore tous les chemins récursifs, mais sa complexité le rend inadapté aux grands ensembles de données.

Approche par backtracking (non optimale)

Cette technique récursive tente d'explorer tous les sauts possibles. Elle est simple mais dépasse souvent le temps limite pour les grands tableaux.

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        found = False
        def backtrack(curr_pos):
            nonlocal found
            if curr_pos == len(nums) - 1:
                found = True
                return
            if curr_pos >= len(nums):
                return
            for step in range(1, nums[curr_pos] + 1):
                backtrack(curr_pos + step)
        backtrack(0)
        return found

Programmation dynamique récursive avec mémoïsation

En utilisant un cache pour stocker les résultats intermédiaires, cette version améliore l'efficacité en évitant les calculs redondants.

from functools import lru_cache

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        @lru_cache(maxsize=None)
        def dp(idx):
            if idx == len(nums) - 1:
                return True
            if idx >= len(nums):
                return False
            for jump in range(1, nums[idx] + 1):
                if dp(idx + jump):
                    return True
            return False
        return dp(0)

Programmation dynamique avec tableau itératif

On construit un tableau booléen de droite à gauche pour déterminer si chaque position est accessible.

class Solution:
    def canJump(self, nums: List[int]) -> bool:
        reachable = [False] * len(nums)
        reachable[-1] = True
        for i in range(len(nums) - 2, -1, -1):
            max_step = nums[i]
            for step in range(1, max_step + 1):
                if i + step < len(nums) and reachable[i + step]:
                    reachable[i] = True
                    break
        return reachable[0]

Une approche greedy basée sur la portée maximale peut aussi résoudre le problème en temps linéaire, mais n'est pas détaillée ici.

Étiquettes: leetcode Programmation-Dynamique backtracking Python algorithmes

Publié le 24 juin à 20h40