Java description LeetCode, 45. Jump Game II jump game II

Keywords: Java leetcode Dynamic Programming

Hello everyone, I'm hehaige and focus on the back end. If I can, I want to be a code designer instead of an ordinary coder to witness the growth of hehaige. Your comments and praise are my biggest driving force. If you have any mistakes, please don't hesitate to comment. Thank you very much. Let's support the original! If there is a clerical error in pure hand typing, please forgive me.

1-1: title

Given an array of non-negative integers nums, 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.

You can assume that you can always reach the last index

Example 1:

Input: nums = [2,3,1,1,4]
Output: 2
Explanation: 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.

Example 2:

Input: nums = [2,3,0,1,4]
Output: 2

Constraints:

1 <= nums.length <= 104
0 <= nums[i] <= 1000

Source: LeetCode
Link: https://leetcode-cn.com/problems/jump-game-ii

1-2: dynamic programming solution

1-2-1: idea

  • Determine status dp[i]: the minimum number of jumps required to reach the position of index=i;
  • State transition equation: if you stand at the initial position of index=0, the range it can reach is 1~nums[i]. For the index in this range, I can reach it only once starting from 0. At this time, it is i=1. When i=1, a situation can occur. If nums [1] > 1, there will be an overlapping range with the range that can be reached when i=0, The index within this range can be reached in one step through i=0 or in two steps through i=1, so it should be judged in the overlapping range each time.
  • Determine the boundary: it is easy to see that dp[0] = 0 when i=0;
  • Traversal order, from left to right.

1-2-2: Code

public static int jump(int[] nums) {
    int n = nums.length;

    int[] dp = new int[n];
    dp[0] = 0;
    for (int i = 1; i < n; i++) {
        dp[i] = Integer.MAX_VALUE;
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j - i <= nums[i]; j++) {
            if (j < n) {
                dp[j] = Math.min(dp[j], dp[i] + 1);
            }
        }
    }
    System.out.println(Arrays.toString(dp));
    return dp[n - 1];
}

Code Notes:

  • You cannot assign integer.max while traversing i_ VALUE. Because this is assigned by dp[j], there are several positions in the range, and only one is assigned Integer.MAX_VALUE, the others are still 0. Of course, taking the minimum value will use 0 instead of the real number of steps. Just try this.
  • Here are multiple assignments in the range, and the left side of the equation of the state transition equation is dp[j] instead of dp[i].

Time complexity O(n^2), space complexity O(n), form the habit of writing complexity, starting today.

1-3: greedy algorithm solution 1

Remember jumping game 1 before? In my last blog, I tried to skip the overlapped part, but I failed, but this idea was used here again, and this problem was successfully solved. The previous problem was that I was so eager to calculate the overlap that I skipped some middle parts. For details, please refer to: Java description LeetCode, 55. Jump Game jumping game 1-4-2, it may take a few minutes. If you don't want to see it, you can skip it and look directly at the idea below.

1-3-2: idea

Greedy, how can I be greedy here? When index=0, it can reach: [1: num [i]], so how can I choose the next position? The total number of times is the least. Under decomposition, you have to go further each time, so you just need to select the one that can reach the farther jump for the second time in [1: num [i]] as the foothold of the first jump. By analogy, this thought really saves some road in the middle. Still, it's better not to be perfect, which will lead to some repeated traversal.

1-3-3: Code

 public static int jump(int[] nums) {
    public static int jump(int[] nums) {
        int n = nums.length;
        if (n == 1) {
            return 0;
        }

        int i = 0; // i represents the position of each fall
        int next = 0; // Next represents the next location
        int count = 0;
        while (i < n) {
            // If you can reach the last index by yourself, you don't need to continue jumping
            if (i + nums[i] >= n - 1) {
                count++;
                return count;
            }

            // Start looking for the next jump
            int j = i + 1;
            //For the position i can reach, see where the next position can be at most
            int maxInstance = Integer.MIN_VALUE;
            while (j < n && j - i <= nums[i]) {
                if (j + nums[j] >= maxInstance) {
                    maxInstance = j + nums[j];
                    next = j;
                }
                j++;
            }
            i = next;// Jump once
            count++;
//            if (i >= n - 1) {
//                return count;
//            }
        }
        return -1;
    }
 }

This is my own code and my own ideas. But it's not easy to write this code right. First of all, there are several points to pay attention to his border situation.

  • When will we find the next foothold?
    • If in one position, the farthest distance I reach includes the end position, naturally I don't have to continue jumping. This should be placed at the beginning of the while loop,
    • If I can't reach the end in one position, I need to find a foothold.

Time complexity O(n^2), space complexity O(1)

1-4: greedy algorithm solution 2

1-4-1: idea

The solution of the answer is the same idea, but it is not done by determining the next step above. It uses a max to determine the range that can be reached in the next step. End records the maximum range that can be reached in the current step. While traversing the num [] array, it determines the maximum range MaxPosition that can be reached in the next step. Once the maximum range of the previous step is reached, end, Enter the next larger range MaxPosition, and the number of steps should be + 1. Note that the last step must be reached.

1-4-2: Code

public static int jump2(int[] nums) {
    int length = nums.length;
    int end = 0;
    int maxPosition = 0;
    int steps = 0;
    for (int i = 0; i < length - 1; i++) {
        maxPosition = Math.max(maxPosition, i + nums[i]);
        if (i == end) {
            end = maxPosition;
            steps++;
        }
    }
    return steps;
}

The code is simple, but I can't think of it. Hahaha, it's seconds again!
Time complexity O(n^2), space complexity O(1)

1-5: summary

There are mainly three solutions, two greedy and one dynamic programming. The first two are written by myself. It's OK. I can't think of the answer. It's accumulation! Come on hhg. Long live the original!

Posted by Eratimus on Thu, 02 Dec 2021 10:42:41 -0800