leetcode 55 跳跃游戏(贪心算法)

给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。

示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。

示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

思路:从第i个位置,最远可跳nums[i]步,确定最终是否可以跳至最后一个位置,最困难的地方在于:无法直观的观察从第0个位置开始依次向后的跳跃方式
例如: [2,3,1,1,4]
从第0位置,可以跳跃至第1位置或第2位置;
从第1位置,可以跳跃至第2、第3、第4位置;
从第2位置,可以跳跃至第3位置
…………
最初在位置0时,应该如何选择,跳跃第1位置还是第2位置?
若选择跳至了第1个位置,之后又该跳跃至第2、第3、第4个位置的哪一个?
将从第i个位置,最远可跳nums[i]步,转化为,从第i个位置,最远可跳至第index[i]个位置;
即index[i] = i + nums[i]; index = [2,4,3,4,8]
若从第0位置最远可以跳至第i个位置
则从第0位置也一定可以跳至:
第1个位置、第2个位置、……、第i-1的位置
那选择从第0个位置,应该跳至第1、第2、……、第i-1、第i个位置中的那个?
应该跳至第1、2、……、i-1、i位置中,又可以向前跳至更远位置;
即index[1]、index[2]、……、index[i-1]、……、index[i]最大的那个位置(贪心);

若此时处在第i个位置,该位置最远可以跳至第j位置,故第i位置还可以跳至第i+1、i+2、……、j-1、j位置。从第i位应跳至第i+1、i+2、……、j-1、j位中可以跳的更远位置的位置,即index[i+1]、index[i+2]、……、index[j-1]、index[j]最大的那个。
假设该位置位x,index[x]最大,故从位置x出发,可以跳至i+1、i+2、……、j-1、j所有位置可以达到的位置;所以跳至位置x最理想。
算法思路:
1、求从第i位置最远可跳至第index[i]位置;
2、初始化:
1)设置变量jump代表当前所处的位置,初始化为0;
2)设置变量max_index代表从第0个位置至第jump位置这个过程中,最远可到达的位置,初始化index[0];
3)利用jump扫描index数组,直到jump达到index数组尾部或者jump超过max_index.扫描过程中更新max_index;
4)若最终jump为数组长度,则返回true,否则返回false;

class Solution {
public:
    bool canJump(vector<int>& nums) {
        vector<int> index;   //最远可跳至的位置
        for(int i = 0; i < nums.size(); i++){
            index.push_back(nums[i] + i);
        }
        int jump = 0;   //初始化jump与max_index
        int max_index = index[0];
        while(jump < nums.size() && jump <= max_index){
            if(max_index < index[jump]){
                max_index = index[jump];
            }
            jump++;
        }
        if(jump == nums.size()){
            return true;
        }
        return false;
    }
};
发布了65 篇原创文章 · 获赞 4 · 访问量 1013

猜你喜欢

转载自blog.csdn.net/CLZHIT/article/details/103665353