Post

LeetCode 55. Jump Game

LeetCode 55. Jump Game

This post was migrated from Tistory. You can find the original here.

Problem

https://leetcode.com/problems/jump-game/description/?source=submission-noac

Approach

My first instinct was DP.

If $ A_{n-1}, A_{n-4}, A_{n-7} …. $ can all jump to $ A_{n} $,

then I’d keep looking for which elements $ A_{n-4}, A_{n-6}, A_{n-7} …. $ can jump to $ A_{n-1} $, and so on,

updating dp to True if I could eventually reach $ A_{0} $, and False if I couldn’t.

So the idea was: run the logic for every case that reaches $ A_{n} $, and if a value was already in the DP table, treat it as a shortcut since it had already been computed from some other case.

But it turns out DP wasn’t necessary at all.

Any element that can jump to $ A_{n-1} $ also belongs to the set of elements that can jump to $ A_{n} $. For example, an $ A_{n-4} $ that can reach $ A_{n} $ cannot possibly fail to reach $ A_{n-1} $.

In other words, instead of running the logic for every case that reaches $ A_{n} $, you can just walk backward from $ A_{n} $ and simply update the target element as you go.

The original approach wasn’t drastically slow either, since the DP gave it a shortcut, but it did extra unnecessary work, so it ends up slower than the version without DP. And the version without DP is much cleaner.

Also, if you write this recursively, you end up spending a lot of time chasing down edge cases you missed.

1
2
3
4
5
6
7
8
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        target = len(nums) - 1
        for i in range(len(nums)-2, -1, -1):
            distance = target - i
            if nums[i] >= distance:
                target = i
        return True if target == 0 else False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Logic with DP

class Solution:
    dp = []
    def logic(self, nums, target):
        if target == 0:
            return True
        for i in range(target-1, -1, -1):
            distance = target - i
            if nums[i] >= distance:
                if self.dp[i] == True:
                    return True
                elif self.dp[i] == False:
                    continue

                if self.logic(nums, i):
                    self.dp[i] = True
                    return True
                else:
                    self.dp[i] = False
        return False

    def canJump(self, nums: List[int]) -> bool:
        leng = len(nums)
        self.dp = [ "x" for i in range(leng) ]
        return self.logic(nums, leng-1)
This post is licensed under CC BY-NC 4.0 by the author.