【LeetCode贪心#04】跳跃游戏I + II
跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
- 输入: [2,3,1,1,4]
- 输出: true
- 解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
- 输入: [3,2,1,0,4]
- 输出: false
- 解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置
思路
题目只需要判断能不能跳到终点,还是比较好想的
根据示例和题目说明,"可以跳跃的最大长度"的定义如下:(注意,其本身也算一个可跳跃距离)
[2,3,1,1,4]
-----
2的跳跃范围是虚线内([2,3,1])
然后我们可以遍历当前元素的可跳跃范围,找到更大的数去扩大可跳跃范围
例如当遍历到3时,可遍历范围扩大至最后一个位置
[2,3,1,1,4]
-------
此时就满足了题目的条件,可以返回true
用贪心的话术来说就是:
局部最优解:每次遍历时争取最大的当前遍历值去更新可跳跃范围
全局最优解:最后得到整体的最大可跳跃范围,看看能不能到终点
代码
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size() == 1) return true;//只有一个数时默认可以跳一步,直接返回true
int jumpScope = 0;//定义变量表示当前可以跳的范围
for(int i = 0; i <= jumpScope; ++i){//在可跳跃范围内遍历,找新的数取扩充这个范围
//在当前遍历值表示的跳跃范围内继续遍历找新的值来更新覆盖范围,取最大的值
jumpScope = max(i + nums[i], jumpScope);//注意,jumpScope表示的是下标
if(jumpScope >= nums.size() - 1) return true;
}
return false;
}
};
跳跃游戏II
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
示例:
- 输入: [2,3,1,1,4]
- 输出: 2
- 解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。
说明: 假设你总是可以到达数组的最后一个位置。
思路
这里就不太一样了,我们还需要考虑怎么跳,跳跃次数最少
具体做法是,在当前值的遍历范围内遍历,每次的遍历结果保存到一个变量中(总保存当前最大的),这个变量是下次跳跃的范围。
举个例子:

遍历开始时,初始跳跃范围是[2](默认有一步,这就是为什么如果只有一个元素的话直接返回true)
遍历[2],记录2为下次跳跃范围,发现默认给的一步到不了数组的末尾,好的,使用当前记录的2作为下次跳跃的范围
此时,跳跃范围第一次扩展到[2,3,1],当前的遍历下标走到3,更新下次跳跃范围为3(因为3比之前的2大)
记录跳跃次数res = 1。
继续遍历,遍历到1, 1小于3所以此时不用更新下次跳跃范围
好了,第一次拓展的跳跃范围([2,3,1])已经遍历完毕,此时仍未达到数组末尾,因此需要再次拓展遍历范围,使用记录的最大的下次跳跃范围进行拓展(即3)
第二次扩展跳跃范围到[3, 1, 1, 4],和上面一样,开始遍历这个新的范围,并从中寻找最大值作为下一次跳跃的范围
记录跳跃次数res = 2。
但是这次把跳跃范围遍历完之后,发现到数组末尾了,所以可以直接结束
从上面的过程可以发现,只有在当前跳跃范围不足时我们才会去扩展跳跃范围,且扩展时是以当前范围中的最大值为依据进行的
每扩展一次就相当于进行了一次跳跃,只不过这次跳跃是最优的跳跃(因为选择了最大值)
这里的贪心思想是:
局部最优--找到当前跳跃区间内的最大值作为下次跳跃的区间
全局最优--总使用最大的值作为跳跃区间,进而达到以最少的跳跃次数到达数组末尾的目的
代码
主要思路和前一题差不多,区别在于需要记录下一次跳跃使用的范围以及跳跃次数
步骤:
1、判断是否只有一个元素,是就直接返回0
2、定义变量,用于保存下次/当前跳跃区间和跳跃次数
3、遍历数组(注意和上体的区别,上题是只遍历当前跳跃范围),不断寻找更大的值来更新nextJumpscope
4、判断当前跳跃区间是否遍历完成
- 如果遍历完了,判断是否到数组末尾
- 到了就结束break
- 没到就记录跳跃次数,并将当前跳跃区间curJumpscope更新为下次跳跃区间nextJumpscope(并判断nextJumpscope是否超出数组长度,超出也可直接结束)
class Solution {
public:
int jump(vector<int>& nums) {
//如果数组只有一个元素,直接返回
if(nums.size() == 1) return 0;
//定义变量保存下次/当前跳跃区间、跳跃次数
int nextJumpscope = 0;//下次跳跃的区间值
int curJumpscope = 0;//当前跳跃的区间值
int jumpCount = 0;//跳跃次数记录
for(int i = 0; i < nums.size(); ++i){//遍历数组(在curJumpscope范围内)
//不断寻找更大的值来更新nextJumpscope
nextJumpscope = max(i + nums[i], nextJumpscope);
if(i == curJumpscope){//如果当前区间遍历完了,就使用nextJumpscope作为跳跃值进行下一次跳跃
if(curJumpscope != nums.size() - 1){//如果当前区间遍历完都没到数组末尾,那么需要跳跃到新的区间
jumpCount++;
curJumpscope = nextJumpscope;
if(nextJumpscope >= nums.size() - 1) break;//如果下次更新的跳跃区域大于数组长度,直接结束
}else break;////如果当前区间遍历完已经到数组末尾,结束
}
}
return jumpCount;
}
};
【LeetCode贪心#04】跳跃游戏I + II的更多相关文章
- Leetcode题目55.跳跃游戏(贪心算法-中等)
题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出: ...
- 贪心——55. 跳跃游戏 && 45.跳跃游戏II
给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] 输出: true ...
- [LeetCode] Jump Game 跳跃游戏
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- 力扣Leetcode 45. 跳跃游戏 II - 贪心思想
这题是 55.跳跃游戏的升级版 力扣Leetcode 55. 跳跃游戏 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃 ...
- leetcode 55. 跳跃游戏 及 45. 跳跃游戏 II
55. 跳跃游戏 问题描述 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1, ...
- Leetcode力扣45题 跳跃游戏 II
原题目: 跳跃游戏 II 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: ...
- LeetCode 45. 跳跃游戏 II | Python
45. 跳跃游戏 II 题目来源:https://leetcode-cn.com/problems/jump-game-ii 题目 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素 ...
- [LeetCode] 45. Jump Game II 跳跃游戏 II
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- Java实现 LeetCode 45 跳跃游戏 II(二)
45. 跳跃游戏 II 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [ ...
- [leetcode] 45. 跳跃游戏 II(Java)(动态规划)
45. 跳跃游戏 II 动态规划 此题可以倒着想. 看示例: [2,3,1,1,4] 我们从后往前推,对于第4个数1,跳一次 对于第3个数1,显然只能跳到第4个数上,那么从第3个数开始跳到最后需要两次 ...
随机推荐
- [转帖]一次python服务的性能优化经历
https://juejin.cn/post/7208708762265616421 问题背景: 在我们的业务中,有一些推荐的场景会需要走到集团研究院的算法推荐服务,对一些用户进行个性化的课件推荐 ...
- [转帖]Linux性能测试之LTP
https://www.modb.pro/db/487946 hello,大家好,今天为大家更新一篇关于Linux性能测试的文章,大家都知道在Windows下测试计算机的性能,我们可以使用鲁大师等软件 ...
- TypeScript枚举类型
枚举 简单理解就是将所有的情况列举出来. 枚举不是用来定义类型的哈.就是说枚举不是一种数据类型. enum xxx={ key1=value1, key2=value2, } 通过 xxx.key1的 ...
- 【K哥爬虫普法】微信公众号爬虫构成不正当竞争,爬虫er面对金山,如何避免滥用爬虫?
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...
- gin启动https支持
gin是一个使用Go语言开发的Web框架,具有运行速度快,分组的路由器,良好的崩溃捕获和错误处理,支持中间件等. 在工作中有时候需要支持https服务,gin可以通过中间件的方式来提供对https的支 ...
- 一文总结现代 C++ 中的初始化
本文尝试回答: 现代 C++ 有哪几种初始化形式?分别能够用于什么场景?有什么限制? MyClass obj(); 为什么没有调用默认无参构造函数创建一个对象? new int 和 new int() ...
- 最新 Hugging Face 强化学习课程(中文版)来啦!
人工智能中最引人入胜的话题莫过于深度强化学习 (Deep Reinforcement Learning) 了,我们在 2022 年 12 月 5 日开启了<深度强化学习课程 v2.0>的课 ...
- 从零开始配置 vim(7)——自动命令
这篇我们来谈论vim一个相当重要的东西--自动命令. 从编程的角度来看,自动命令有点类似于事件响应,或者回调函数之类.当外部发生某些事件的时候,自动执行事先定义好的一组命令. 定义一个自动命令的格式如 ...
- FFmpeg的录制命令
FFmpeg的录制命令 命令的作用 它可以捕捉桌面窗口,摄像头的视频流和麦克风的音频流. 命令的格式 ffmpeg [输入格式] [输入选项] -i [输入设备索引] [输出选项] 输出文件 其中输入 ...
- 【链表】双向链表的介绍和基本操作(C语言实现)【保姆级别详细教学】
双向链表 文章目录 前言 双向链表的基本介绍 一些链表的分类 带头双向循环链表的基本结构 双向链表的实现 结点的定义.头指针的创建 开辟结点接口 初始化头结点接口 打印接口 尾插接口 尾删接口 头插接 ...