【leetcode】Jumping Game II (Greedy)

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

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

Your goal is to get to the last position of the array using the fewest number of jumps.

Example:

Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to jump to the last position is 2.
Jump from index 0 to index 1, jump 1 step, then jump 3 steps to the last position in the array.
illustrate:

Assuming you can always reach the last position of the array.

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

Thought analysis:

This problem can be considered greedy, from this condition: each element in the array represents the maximum length you can jump at that position. This means that the range you can jump is an interval.
The problem requires the least number of jumps to reach the end, and we can greedily jump to the farthest place every time.
Take [2,3,1,1,4] as an example:
The intuitive idea at the beginning may be the longest distance jumped each time, and 0-2-3-4 jumped 3 times. However, the answer is 2 times: 0-1-4.
This means that we need to consider all the points that can jump from the current position, and then select the point that can jump to the farthest position from all the points.
We define a state Max to represent the farthest position that can be jumped among all the points in the current jumpable range.
We define a state idx to represent the point that can jump to the farthest position among all the points in the current jumpable range.

The proof of the greedy correctness of this question is more complicated, but thinking about it according to this idea should be able to deduce it in your mind.

class Solution {
    
    
public:
    int jump(vector<int>& nums) {
    
    
        int n = nums.size();
        //Max表示在当前可跳范围内的所有点中,所能跳到的最远位置
        //idx表示在当前可跳范围内的所有点中,能跳到最远位置的点
        int Max = nums[0], idx = 0, cur = 0, ans = 0;
        while(cur < n-1)
        {
    
    
            //如果可跳到的最后一个位置,返回当前步数+1(还需要一步跳到终点)
            if(Max >= n-1) return ans+1;    
            //遍历当前可跳范围内的所有点,找到能跳最远位置的点. min是为了防止数组下标越界
            for(int i = cur+1;i <= min(n-1,cur+nums[cur]);i++) 
            {
    
    
                if(Max < i+nums[i]) //更新Max和idx
                {
    
    
                    Max = i+nums[i];
                    idx = i;
                }
            }
            cur = idx, ans++; //跳到该点并步数+1           
        }
        return  ans;
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325641779&siteId=291194637