[LintCode/LeetCode] Jump Game I & II

346 查看

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;
    }
}