[LintCode/LeetCode] Jump Game I & II

本文解析了JumpGame及其II版的问题,介绍了使用动态规划与贪心算法两种方法解决这些问题的思路及实现方式。对于JumpGame I,重点在于判断能否达到最后一个位置;而JumpGame II则需找出到达最后一个位置所需的最少跳跃次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Jump Game

Problem

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

Notice

This problem have two method which is Greedy and Dynamic Programming.

The time complexity of Greedy method is O(n).

The time complexity of Dynamic Programming method is O(n^2).

We manually set the small data set to allow you pass the test in both ways. This is just to let you learn how to use this problem in dynamic programming ways. If you finish it in dynamic programming ways, you can try greedy method to make it accept again.

Example

A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

Note

建立动规boolean数组dp,表示从起点A[0]处到达该点的可能性。所以,起点的可能性dp[0] = true
然后进行两次循环,令j < i,当dp[j]truej点可以到达i点时,dp[i]也为true
循环结束后,dp数组对所有点作为终点的可能性都进行了赋值。返回数组A的终点dp[A.length-1]即可。

Solution

DP

public class Solution {
    public boolean canJump(int[] A) {
        int n = A.length;
        boolean[] dp = new boolean[n];
        dp[0] = true;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (dp[j] && j + A[j] >= i) dp[i] = true;
            }
        }
        return dp[n-1];
    }
}

Greedy

public class Solution {
    public boolean canJump(int[] A) {
        int n = A.length;
        if (n <= 1) return true;
        for (int i = n-2; i >= 0; i--) {
            if (A[i] == 0) {
                int need = 1;
                while (need > A[i]) {
                    need++;
                    i--;
                    if (i < 0) return false;
                }
            }
        }
        return true;
    }
}

Jump Game II

Problem

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

Example

Given array A = [2,3,1,1,4]

The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

Note

Jump Game I的不同在于找到最少的步数。这里有一个很巧妙的思想就是,ij既然都是从起点开始遍历,每一个点i只要满足j + A[j] >= i,证明有解,就break出来。此时的j一定是满足条件的最小的j,所以dp[i] = dp[j] + 1一定是最优解。

Solution

DP

public class Solution {
    public int jump(int[] A) {
        int n = A.length;
        int[] dp = new int[n];
        for (int i = 0; i < n; i++) {
            dp[i] = 0;
            for (int j = 0; j < i; j++) {
                if (j + A[j] >= i) {
                    dp[i] = dp[j]+1;
                    break;
                }
            }
        }
        return dp[n-1];
    }
}

Greedy

public class Solution {
    public int jump(int[] A) {
        int step = 0, lastMax = 0, curMax = 0;
        for (int i = 0; i < n-1; i++) {
            //Find the farthest point you can reach from current point
            curMax = Math.max(curMax, i+A[i]);
            //When reaching current step max distance
            //Add a new step; set the new step max distance to reach
            if (i == lastMax) {
                step++;
                lastMax = curMax;
            }
        }
        return step;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值