首页 > 贪心:jump 游戏(获取最少跳跃的次数以及跳跃路径)

贪心:jump 游戏(获取最少跳跃的次数以及跳跃路径)

一个数组存储了非负整型数据,数组中的第i个元素a[i],代表了可以从数组第i个 位置最多向前跳跃a[i]步;已知数组各元素的情况下,求是否可以从数组的第0个位置跳跃到数组的最后一个元素的位置,返回最少跳跃的次数以及跳跃过程的路径(以数组下标标识)

例如:

nums = [2, 3, 1, 1, 4] ,可以从nums[0] = 2 跳跃至 nums[4] = 4; 最少跳跃次数为2,跳跃路径为[0,1,4]

该跳跃过程和判断最终节点是否可达类似,不过需要注意一点:为了保证获取到的跳跃次数是最少的,需要在每一次的跳跃范围中尽可能得跳跃更多的节点,且在第一次跳跃结束后获取到后续所有节点的跳跃范围之后再进行下一次跳跃。

贪心规律:

在无法到达更远的地方时,在这之前应该跳到一个可以到达更 远位置的位置!

在这里插入图片描述

类似如上,在index[i]的节点上无法跳跃到更远的节点了,此时应该选择index[i-2],使得其能够跳跃更远的节点。

同时如果想要获取跳跃的路径,即可将跳跃过程中发生的节点更替的时的下标记录下来,在跳跃的过程中加入到路径数组即可。

实现过程如下:

/*获取最少的跳跃次数*/
int get_judge_finish(vector<int> &stage) { if (stage.size() < 2) { return 0;}int current_max_pos = stage[0]; //当前能够跳跃到的最远的节点int pre_max_pos = stage[0];    //各个位置能够跳跃到的最远的节点int least_jum = 1;for (int i = 0;i < stage.size(); ++i) { if(i > current_max_pos) {  //当遍历完当前节点当范围时进行跳跃,跳跃点选择各个位置能够跳跃当最远的点least_jum ++;current_max_pos = pre_max_pos;}if (pre_max_pos < stage[i] + i){  //获取各个位置能够跳跃到的最远的点pre_max_pos = stage[i] + i;}}return least_jum;
}/*获取最少的跳跃路径*/
vector<int> get_jump_path(vector<int> &stage) { if (stage.size() < 2) { return stage;}int current_max_pos = stage[0];int pre_max_pos = stage[0];int pre_max_index = 0; //记录各个位置能够跳的最远的节点下标vector<int> jump_path; //记录跳跃路径jump_path.push_back(0); //开头节点起跳for (int i = 0;i < stage.size(); ++i) { if(i > current_max_pos) { current_max_pos = pre_max_pos;/*当开始跳时,记录的各个位置能够跳的最远的下标*/jump_path.push_back(pre_max_index); }   if (pre_max_pos < stage[i] + i){ pre_max_pos = stage[i] + i;pre_max_index = i;}}jump_path.push_back(stage.size()-1);return jump_path;
}

测试代码如下:

#include 
#include using namespace std;
/*判断是否能够完成跳跃*/
bool judge_finish(vector<int> &stage) { vector<int> index;for (int i = 0; i < stage.size(); ++i) { index.push_back(i + stage[i]);}int max_index = stage[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;}return false;
}
/*获取最少的跳跃次数*/
int get_judge_finish(vector<int> &stage) { if (stage.size() < 2) { return 0;}int current_max_pos = stage[0];int pre_max_pos = stage[0];int least_jum = 1;for (int i = 0;i < stage.size(); ++i) { if(i > current_max_pos) { least_jum ++;current_max_pos = pre_max_pos;}if (pre_max_pos < stage[i] + i){ pre_max_pos = stage[i] + i;}}return least_jum;
}
/*获取跳跃路径*/
vector<int> get_jump_path(vector<int> &stage) { if (stage.size() < 2) { return stage;}int current_max_pos = stage[0];int pre_max_pos = stage[0];int pre_max_index = 0;vector<int> jump_path;jump_path.push_back(0);for (int i = 0;i < stage.size(); ++i) { if(i > current_max_pos) { current_max_pos = pre_max_pos;jump_path.push_back(pre_max_index);}   if (pre_max_pos < stage[i] + i){ pre_max_pos = stage[i] + i;pre_max_index = i;}}jump_path.push_back(stage.size()-1);return jump_path;
}int main() { vector<int> s;int tmp;cout << "input arr " <<endl;for (int i =0;i < 5; ++i) { cin >> tmp;s.push_back(tmp);}cout << "the least times to jump is " << get_judge_finish(s) << endl;cout << "the true or false that judge the result is " << judge_finish(s) << endl;cout << "jump path is " << endl;vector<int> path = get_jump_path(s);for (int i = 0;i < path.size(); ++i) { cout << path[i] << " ";}return 0;
}

输出如下:

input arr 
3 2 2 0 5
the least times to jump is 2
the true or false that judge the result is 1
jump path is 
0 2 4input arr 
2 3 1 1 4
the least times to jump is 2
the true or false that judge the result is 1
jump path is 
0 1 4 

更多相关:

  •         Apache POI是一个开源的利用Java读写Excel,WORD等微软OLE2组件文档的项目。        我的需求是对Excel的数据进行导入或将数据以Excel的形式导出。先上简单的测试代码:package com.xing.studyTest.poi;import java.io.FileInputSt...

  • 要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 要取得a到b之间的...

  • 利用本征图像分解(Intrinsic Image Decomposition)算法,将图像分解为shading(illumination) image 和 reflectance(albedo) image,计算图像的reflectance image。 Reflectance Image 是指在变化的光照条件下能够维持不变的图像部分...

  • 题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2 限制: 1 <= 数组长度 <= 50000 解题: cl...

  • 题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。 参考以下这颗二叉搜索树:      5     /    2   6   /  1   3示例 1: 输入: [1,6,3,2,5] 输出...

  • 给定一个非负整数数组,你最初位于数组的第一个位置。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 示例: 输入: [2,3,1,1,4] 输出: 2 解释: 跳到最后一个位置的最小跳跃数是 2。 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最...