前言
之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两台晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还会给刷的题总结下,谈谈自己的一些思考,和自己的思路等等,希望对小伙伴能有所帮助吧,也可以借此机会把自己短板补一补,希望自己能坚持下去呀
题目
跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
- 输入: [2,3,1,1,4]
- 输出: true
- 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
- 输入: [3,2,1,0,4]
- 输出: false
- 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
思路
刚看到本题一开始可能想:当前位置元素如果是3,我究竟是跳一步呢,还是两步呢,还是三步呢,究竟跳几步才是最优呢?
其实跳几步无所谓,关键在于可跳的覆盖范围!
不一定非要明确一次究竟跳几步,每次取最大的跳跃步数,这个就是可以跳跃的覆盖范围。
这个范围内,别管是怎么跳的,反正一定可以跳过来。
那么这个问题就转化为跳跃覆盖范围究竟可不可以覆盖到终点!
每次移动取最大跳跃步数(得到最大的覆盖范围),每移动一个单位,就更新最大覆盖范围。
贪心算法局部最优解:每次取最大跳跃步数(取最大覆盖范围),整体最优解:最后得到整体最大覆盖范围,看是否能到终点。
代码
package com.six.finger.leetcode.five; /** * 给定一个非负整数数组,你最初位于数组的第一个位置。 * 数组中的每个元素代表你在该位置可以跳跃的最大长度。 * 判断你是否能够到达最后一个位置。 * 示例 1: * <p> * 输入: [2,3,1,1,4] * 输出: true * 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。 * <p> * 示例 2: * <p> * 输入: [3,2,1,0,4] * 输出: false * 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。 */ public class twentyseven { public static void main(String[] args) { } public boolean canJump(int[] nums) { //数组的总长度 int n=nums.length; //记录单词可以跳的最远位置 int rightmost=0; for (int i = 0; i < nums.length; i++) { if (i<=rightmost){ //必须<=才可以继续 //判断最远的位置 rightmost=Math.max(rightmost,i+nums[i]); if (rightmost>=n-1){ return true; } } } return false; } }
- 记录最大值
- 记录单次可以覆盖的最大值,判断当前可以到最大范围,最主要是i<=rihgtmost,如果当前值覆盖不到了,那么就可以直接返回覆盖不到了,
- 最后去判断rightmost >= n - 1
结束
好了,今天的这题贪心就到这了,我是小六六,三天打鱼,两天晒网!