2.跳跃游戏(c++)
一、题目
有一段直线距离,这段距离上分布着 n 个 格子
每个位置上都标有数字,表示可以从这个格子往前最多跳跃几格
最少跳几步,可以从起点跳到终点?
如上图就是需要从A点跳到C点
在A点,可以往前最多跳2格,也就是在A点 可以往前跳一格或者两格
B点就可以看成一个坑,像上图这个例子中,这个坑就是没办法逾越的,所以没办法跳到终点
二、分析
这道题目被归类为贪心算法
贪心算法都有个贪心思想
既然我需要得到最少跳几步,那么我就死活不跳
到了不得不跳的时候,再挑一个跳的最远的位置,来跳
定义a为当前格子,b为当前格子能到的最远距离
像上面这个例子
把A点看成 a,把A点能跳到的最远距离看成 b(也就是第三个位置)
什么叫不得不跳?
A只能走一步或者两步,而我现在就在A点,那么就要考虑在(a,b] 这段距离内
哪个格子能够尽可能地跳的更远,而且一定要选一个格子跳
也就是每次来到一个新格子,就要考察(a,b] 那个格子能跳的更远
所以这里的贪心思想是:不得不跳我再跳,跳了我就选最大的跳
这里我们可能会思考这个“坑”怎么考虑,因为每次选最好的格子跳
最后如果最远只能跳到一个坑里,那自然就是没法越过这个坑,返回失败即可
三、代码
1.main函数
这里我们的jumpGame2()方法返回的是最少需要跳几步
600是设置的跳到坑中的情况
int main(){vector<int> steps;steps.push_back(1);steps.push_back(1);steps.push_back(3);steps.push_back(2);steps.push_back(1);//steps.push_back(0); //注释这一行看这个坑有没有起效steps.push_back(2);steps.push_back(3);steps.push_back(5);steps.push_back(2);Solution solve;int result = solve.jumpGame2(steps);if(result == 0)printf("你只有一个格子或者一个格子都没有,跳0步!");else if(result == 600)printf("你不得不跳入一个坑中,结束一生!");elseprintf("总共需要跳跃%d步!",result);
}
2.解决方案Solution
current_index存放的是 当前这个格子 能到达的最远距离
pre_index存放的是 (a,b]之间的格子 能去往的最远距离
每次指针扫描到current_index+1的时候,也就是不得不做选择
在(a,b]之间选择一个能够跳的最远的格子进行跳远的时候
不得不跳,又只能跳到坑中,之间返回入坑(这里用自己设置的错误码600)
不是做选择的时候,就是挑选(a,b]之间最好的格子,等到不得不跳的时候,就选这个格子来跳
当然,这里还设置了一个小trick,当我在扫描(a,b]的时候
发现有个格子能直接到达或者超过终点,直接选这个节点就对了,也算是小小的贪心,后面的都不考虑了
为什么跳两步,就是跳过被选中的节点,再跳到终点,是两步
class Solution{
public:int jumpGame2(vector<int> steps){//如果格子小于等于1,返回错误1,一步都不跳if(steps.size() <= 1)return 0;//current_index = steps[a]+a;int current_index = steps[0];//pre_index = (a,b] 之间的能去到的最远距离int pre_index = steps[0];//跳跃次数int times = 0;//记录每次跳哪一步int theBestChoise = 0;for(int i = 1;i < steps.size();i++){//指针来到 b+1的位置,不得不跳出一步if(i > current_index){current_index = pre_index;//不得不走一步,只能走到一个坑里面时,结束了if(steps[current_index] == 0)return 600;printf("跳跃到第%d个格子\n",theBestChoise);times++;}//看pre_index 能否被超过if(pre_index < i+steps[i]){theBestChoise = i;pre_index = i+steps[i];if(pre_index >= steps.size()-1){ //能够到终点了,直接退出times = times + 2; //这里连续跳了两步printf("跳跃到第%d个格子,然后直接跳到终点\n",theBestChoise);break;}}}if(pre_index < steps.size()-1)return 600;return times;}
};
3.完整代码
#include <stdio.h>
#include <vector>
using namespace std;
class Solution{
public:int jumpGame2(vector<int> steps){//如果格子小于等于1,返回错误1,一步都不跳if(steps.size() <= 1)return 0;//current_index = steps[a]+a;int current_index = steps[0];//pre_index = (a,b] 之间的能去到的最远距离int pre_index = steps[0];//跳跃次数int times = 0;//记录每次跳哪一步int theBestChoise = 0;for(int i = 1;i < steps.size();i++){//指针来到 b+1的位置,不得不跳出一步if(i > current_index){current_index = pre_index;//不得不走一步,只能走到一个坑里面时,结束了if(steps[current_index] == 0)return 600;printf("跳跃到第%d个格子\n",theBestChoise);times++;}//看pre_index 能否被超过if(pre_index < i+steps[i]){theBestChoise = i;pre_index = i+steps[i];if(pre_index >= steps.size()-1){ //能够到终点了,直接退出times = times + 2; //这里连续跳了两步printf("跳跃到第%d个格子,然后直接跳到终点\n",theBestChoise);break;}}}}
};int main(){vector<int> steps;steps.push_back(1);steps.push_back(1);steps.push_back(3);steps.push_back(2);steps.push_back(1);//steps.push_back(0); //注释这一行看这个坑有没有起效steps.push_back(2);steps.push_back(3);steps.push_back(5);steps.push_back(2);Solution solve;int result = solve.jumpGame2(steps);if(result == 0)printf("你只有一个格子或者一个格子都没有,跳0步!");else if(result == 600)printf("你不得不跳入一个坑中,结束一生!");elseprintf("总共需要跳跃%d步!",result);
}
四、小结
有一些贪心算法的题目的贪心思想就是
我要尽量贪心,就要用最少的资源做最好的事情
怎么用最少的资源呢?就是不得不用,我再去用,这个很关键
分析题目的时候,要找到那个不得不用的时刻,题目就自然得解
2.跳跃游戏(c++)相关推荐
- leetcode-45 跳跃游戏II
给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [2,3,1,1,4] 输 ...
- LeetCode-笔记-45.跳跃游戏II-贪心算法
LeetCode-笔记-45.跳跃游戏II-贪心算法 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后 ...
- 《LeetCode力扣练习》第55题 跳跃游戏 Java
<LeetCode力扣练习>第55题 跳跃游戏 Java 一.资源 题目: 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该位置可以跳跃的最大 ...
- LeetCode 55. 跳跃游戏 中等难度
55. 跳跃游戏 题目: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1:输入: [2,3,1,1, ...
- Leetcode1696. 跳跃游戏 VI[C++题解]:dp和单调队列求滑动窗口最值
文章目录 题目分析 题目链接 单调队列板子链接 Deque知识补充 题目分析 题目重述:给定一个数组(有正数有负数)和一个步长k,从下标0处开始往前跳,每次最多往前跳k步.求跳到最后一个位置,得分之和 ...
- LeetCode:跳跃游戏【55】
LeetCode:跳跃游戏[55] 题目描述 给定一个非负整数数组,你最初位于数组的第一个位置.数组中的每个元素代表你在该位置可以跳跃的最大长度.判断你是否能够到达最后一个位置. 示例 1: 输入: ...
- LeetCode 55跳跃游戏56合并区间57插入区间
原创公众号:bigsai 希望和优秀的你做朋友,感觉不错还请一键三连. 回复进群即可加入和200+人一起打卡.上周打卡: LeetCode 47全排列Ⅱ&48旋转图像 LeetCode 49字 ...
- LeetCode 45跳跃游戏46全排列
原创公众号:bigsai,回复进群加入力扣打卡群. 昨日打卡:LeetCode 42字符串相乘&43通配符匹配 跳跃游戏 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中 ...
- 【LeetCode 55】【LeetCode 45】 跳跃游戏
55. 跳跃游戏 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个位置. 示例 1: 输入: [2,3,1,1,4] ...
- JavaScript实现跳跃游戏的贪婪方法的算法(附完整源码)
JavaScript实现跳跃游戏的贪婪方法的算法(附完整源码) greedyJumpGame.js完整源代码 greedyJumpGame.test.js完整源代码 greedyJumpGame.js ...
最新文章
- ASP .NET Core Web Razor Pages系列教程三:自动生成Razor Pages (CRUD)
- java ipfs文件存储_原来IPFS是这样存储文件的
- 源码解析 React Hook 构建过程
- Output Operations on DStreams
- Java的finally执行顺序_Java return和finally执行顺序
- 计算机ftp无法找到启动路径,filezilla出现路径错误导致无法启动怎么办?filezilla无法启动的解决方法...
- java线程如何避免死锁_Java面试问题,如何避免Java线程中的死锁?
- 重命名Heroku的app
- informix 数据库锁表分析和解决方法
- python拼图游戏代码_教你用Python自制拼图小游戏,轻松搞定熊孩子
- 上班族中流行以貌取人 汉王人脸通变普及
- 一位硕士毕业生三个月求职经历与经验的结晶
- php 英文转中文,php 中英文语言转换的方法
- 清远市高中计算机考试时间,2017年清远市中考体育考试安排
- 闪存联盟启动“百强架构师”行动 迎接认知时代架构挑战
- vue电商后台管理系统--订单管理篇
- 自动化手游测试视频震撼发布
- Redis入门总结(一):redis配置文件,五种数据结构,线程模型和持久化方式
- Java Date Calendar类的使用 如何计算两个日期之间有多少天
- cocos2d-LUA逆向之用idaPro调试so库获取xxtea解密key