【小白爬Leetcode55】3.4 跳跃游戏 Jump Game

【小白爬Leetcode55】3.4 跳跃游戏 Jump Game


Leetcode 55 m e d i u m \color{#FF6347}{medium} medium

点击进入原题链接:Leetcode 55 跳跃游戏 Jump Game

题目

discription

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.

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

中文描述

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

在这里插入图片描述
在这里插入图片描述

思路 贪心算法

每一步都思考当前最佳的结果:

[3,1,3,2,…]
假设我在第i==0个位置,nums[i]为3,意味着我可以前进3步,

  1. 如果我前进1步,那么我到达了第i+1==1个位置,那么做这个决定我最多可以前进1+nums[i+1]==1+1==2步;
  2. 如果我前进2步,那么我到达了第i+2==2个位置,那么做这个决定我最多可以前进2+nums[i+2]==2+3==5步;
  3. 如果我前进3步,那么我到达了第i+3==3个位置,那么做这个决定我最多可以前进3+nums[i+3]==3+2==5步;
    综上,当前最优决策是前进2步或前进3步。

当然,这里有个小细节,就是我们优先选择当前前进步数尽可能长,这样在进行下一步决策的时候,我就可以少考虑些情况,因此,我们选择前进3步而不是2步

这个细节还可以避免一个尴尬的情况,如[3,0,0]这个情况,从头开始走0步,1步,2步都是一样的,但如果优先选择前进步数小则会一直停在位置0,陷入死循环(别问我怎么知道的),优先选择当前前进步数尽可能长,可以避免这个问题。

完整代码如下:

class Solution {
public:
	bool canJump(vector<int>& nums) {
		int i = 0;
		int steps = nums[0];

		while (true) {
			int largest_step = steps;
			int largets_pos = 0;
			for (int j = 1; j < steps + 1; j++) {
				if (i + j >= nums.size() - 1) return true;
				if (largest_step <= j + nums[i + j]) {
					largest_step = j + nums[i + j];
					largets_pos = j;
				}
			}
			i += largets_pos;
			if (i >= nums.size() - 1) {
				return true;
			}
			steps = nums[i];
			if (steps == 0) {
				return false;
			}
		}
	}
};

或者还有个来自B站简洁直观一点的实现:
用一个vector<int> index记录每一个位置下一步所能达到的最大位置,然后遍历这个index的每个元素,找出最大的那个元素。当然,前进的步数jump不可能超过当前max_index的。如果遍历过程中,出现了jump大于max_index的情况,这是超自然现象,说明无法jump到最后一个数字。

class Solution {
public:
	bool canJump(vector<int>& nums) {
        std::vector<int> index;
        for(int i=0;i<nums.size();i++){
            index.push_back(i+nums[i]);
        }

        int max_index = nums[0];
        int jump = 0;
        while(jump<index.size() && jump <= max_index){
            if(max_index<=index[jump]){
                max_index = index[jump];
            }
            jump++;
        }
        if(jump == index.size()){
            return true;
        }
        else return false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值