LeetCode45, Jumping Game II (Dynamic planning cannot pass)

Title description

https://leetcode-cn.com/problems/jump-game-ii/
Insert picture description here

solution

The first thing that comes to mind is to do dynamic programming:

  • Maintain a dp[i] array representing the minimum number of steps required to jump to the index i
  • Then when we recursively dp[i+1], we only need to find the sum of the smallest number of steps that can jump to the coordinate i+1 in the previous i dp[i]
  • Return the dp[nums.length]
    code:
class Solution {
    
    
    public int jump(int[] nums) {
    
    
        //状态:当前的位置i,要到达的位置j,使用的跳跃次数
        if(nums==null || nums.length==0||nums.length==1 ) return 0;
        
        int []dp = new int[nums.length];//表示从0到达下标i所需要的最少跳跃数
        dp[1] = 1;
        for(int i=1;i<nums.length;i++){
    
    
            int step = nums.length;//默认为最大值
            for(int j=0;j<i;j++){
    
    //遍历之前的dp[j],找到一个最少的步数,取之为dp[i];
                if(nums[j]>=i-j){
    
    //从下标j能达到下标i
                    int temp = dp[j]+ 1;//跳跃数加1
                    if(step>temp){
    
    
                        step = temp;
                    }//计算从0走到i,需要的最少步数
                }
            }
            dp[i] = step;//更新从0到i要走的最少步数
        }
        return dp[nums.length-1];

    }
}

The code can pass many test cases, but it will time out: the
Insert picture description here
number of elements is about 25,000, which shows that the complexity of O(n 2 ) cannot survive. Because the dynamic programming has timed out, it shows that the problem is greedy.

Using the greedy algorithm, then we need to think about the greedy choices for this question:

  • Choose the maximum number of steps to jump each time to reach the farthest distance (counter-examples can be given)
  • Choose the smallest number of steps to jump every time to reach the closest distance (obviously not)
  • Every time we choose to jump to all the positions that can be jumped to, the position that can reach the farthest position. For
    example, we are at subscript 0, nums[0] is 3, which means we can jump to three positions 1, 2, 3, and nums [2]=3, the farthest to reach 5, nums[1] = 2, the farthest to reach 3, nums[3]=1, the farthest to reach 1, then we choose to jump to the position with subscript 2, because at this time , The position we can reach is the farthest, which means that we need the least number of jumps to reach the position within the range, only 1 time.
    But if 3 is the end at this time, then we jump directly to 3. So we need to pay a little attention to the subscript processing.

The following picture is from the official problem solution: https://leetcode-cn.com/problems/jump-game-ii/solution/tiao-yue-you-xi-ii-by-leetcode-solution/
Insert picture description here

So we can get the following code:

class Solution {
    
    
    public int jump(int[] nums) {
    
    

        if(nums==null || nums.length==0||nums.length==1 ) return 0;
        int end = 0;//记录当前能跳到的位置的边界
        int jumps = 0,farthest=0;//跳跃次数
        for(int i=0;i<nums.length-1;i++){
    
    //i不一定表示当前位置,但是属于当前位置的边界之内
        //如果end边界=nums.length,不需要step++,所以这里只需要<nums.length-1
            //获取最大的跳远范围
            farthest = Math.max(nums[i]+i,farthest);
            if(end==i){
    
    //到达了边界,开始下一次跳跃,step++
                jumps++;//跳跃数++
                end = farthest;//更新现在的边界,
            }
        }
        return jumps;

    }
}

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_44861675/article/details/114587133