LeetCode(055)-Jump Game(贪心算法最优解/动态规划最优解)

版权声明:中华人民共和国持有版权 https://blog.csdn.net/Fly_Fly_Zhang/article/details/89874490

题目:

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.

Example 1:

Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:

Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum
jump length is 0, which makes it impossible to reach the last index.

翻译:

给定一个非负整数数组,初始位置是数组的第一个索引。
数组中的每个元素表示该位置的最大跳转长度。
确定是否能够达到最后一个索引。
示例1:
输入:[2、3、1、1、4)
输出:真正的
说明:从索引0跳转到1,然后再跳转到最后一个索引,执行3个步骤。
示例2:
输入:[3、2、1、0,4]
输出:假
说明:无论如何,您总是会到达索引3。它的最大
跳转长度为0,因此不可能到达最后一个索引。

方法一: 贪心算法(O(n))

这个题的tag是贪心,贪心策略是我们每次都选取最优的策略,然后前面已经选好了的就不用管了。

这个题的贪心方法是,我们使用一个变量max保存当前能到达的最后位置索引,那么在每个位置的时候判断这个位置能不能到达,即位置的索引大于了max说明前面无论怎么走也走不到这个位置,就返回False好了。如果这个位置可以到达,那么要维护一下这个max,更新策略是当前位置索引+这个数字代表的能向右走多少步,这个代表了到达当前位置的时候向右能到达的最远距离,在这个最远距离以内的任何位置都能到,因为每次跳的步数可以变小的。那么进行了这么一次循环以后,每个位置都判断为能到达,所以结果返回True就好了。

class Solution {
    public boolean canJump(int[] nums) {
        int max=0;//最远可到达位置
        for(int i=0 ; i<nums.length ; i++){
            if(i>max){ //max的最大长度到达不了该角标
                return false;
            }
            //if(i+nums[i]>nums.length-1) //这两句建议在数据量大的时候使用
                //return true;
            
            max=Math.max(max,i+nums[i]);
            //i+nums[i]当前角标往后延伸的最长距离
        }
        return true;
    }
}
方法二:动态规划

我们进一步进行分析,如果数组中每个角标位置元素都不为0,那么肯定是可以到达最后位置的,因此,我们只需要找到数组中元素为0的点,在遍历其前面角标元素,看其前面元素是否能超过此角标,如果有则表明能到达此位置。

class Solution {
    public boolean canJump(int[] nums) {
        for(int i=nums.length-2 ; i>=0 ;i--){
         //为啥从到数第二个开始,因为倒数第一的角标是多少我们是不care的,
         //只要别的元素能jump到它就可以。
            if(nums[i]==0){ //当前角标位置为0,找到能跳过此位置的元素。
                int needjump=1; //需要跳跃的长度
                while(needjump>nums[i]){ 
                //切记,遍历的角标元素是不能相加的。
                    needjump++;
                    i--;
                    if(i<0) //数组遍历完依然没有找到。
                        return false;
                }
            }
        }
        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/Fly_Fly_Zhang/article/details/89874490