Jump Game II
来源:互联网 发布:pp手机助手 mac 编辑:程序博客网 时间:2024/05/21 17:44
Jump Game II - LeetCode
大概翻译一下题目的意思,有一个非负整数数组,数组某个index上的数值代表在这个index上能跳的最大步数,要从这个数组的第一个位置跳到最后一个位置,求跳动的最少次数。
例:A = [2,3,1,1,4]
从A[0]开始跳,A[0]=2,所以在这个位置最多能跳2步。
如果跳两步那么就到了A[2],而A[2]=1所以在这个位置只能跳1步
显然这个样例的答案是2,在A[0]跳1步,到达A[1],再从A[1]跳3步到达数组最后一个位置
先写一下我的2B方法
题目要求最少的次数,显然可以用BFS做
具体的做法是用一个队列存储当前的位置,然后把从这个位置能到达的所有其他位置按顺序(按什么顺序视情况而定,后面会提到)压入队列,
另外再创建一个队列用来记录到达当前位置已用的步数
这样已经可以得到正确答案了,但是效率不高,所以提交的时候超时了,因为很多节点会被重复考虑,举个例子
比如B=[2,2,2,1,4],到达B[2](注意是B[2])有两种方法:
1.先跳1步,再跳1步,共跳2次
2.跳两步,共跳1次
显然这里只需要考虑第2种方法就行,因为不论用哪种方法,到达B[2]后,接下来的情况是相同的,而第一种方法已经跳了2次,最后的跳动次数一定会比第二种方法多。
所以要去掉这种重复冗余的情况,去掉的方法就是用一个set存储已经经过的节点,当再次到达该节点时就忽略。
为什么这样就能起作用?因为在做BFS的时候,某个index可能会被到达多次,但是第一次到达该index所用的跳动次数一定是最少的
优化之后过了91/92个测试,就差了1个。。
这时候就要考虑顺序了,,我一开始是按步数递增的顺序把下一个index压入队列的。这样做的结果是,每次都优先考虑了跳一步的情况,,所以会很慢,,,于是改了一下顺序,按步数递减的顺序把下一个index压入队列,这样就会优先考虑跳动步数最大的情况。
#include <iostream>#include <vector>#include <queue>#include <set>using namespace std;class Solution {public: int jump(vector<int>& nums) { int n = nums[0], p = 0, i = 0, steps = 0; set<int> s; queue<int> pos; queue<int> step; s.insert(0); pos.push(0); step.push(0); while (!pos.empty() && p < nums.size()-1) { p = pos.front(); pos.pop(); steps = step.front(); step.pop(); steps++; for (i = nums[p]; i >= 1; i--) { //这里改动了顺序 if (p + i == nums.size()-1) break; if (s.find(p+i) == s.end()) { pos.push(p+i); step.push(steps); s.insert(p+i); } } if ((p + i == nums.size()-1) && (i != nums[p]+1)) break; } return steps; }};
结果不是太好,看了别人的方法才知道可以把两个队列合并成1个队列,用pair就行。。这样就会少很多次pop,push操作
下面是效率最高的做法
class Solution {public: int jump(vector<int>& nums) { int cnt = 0; int maxidx = 0; int curidx = 0; for(int i=0; i<nums.size()-1; i++){ maxidx = max(maxidx, nums[i]+i); if(i==curidx){ cnt++; curidx = maxidx; } } return cnt; }};
代码很简洁,仔细去理解一下这个代码会发现其实这个方法有些投机的成分,为什么这么说?
题目里最后有个note说,“你可以认为你永远能够到达最后一个index”,大多数人会认为这个条件是题目的一个简化,可以让我们少考虑一些情况,但是这个解法重分利用了这个条件——“你总是能够到达最后一个index”。
这解法的思路是“尽可能地走往后走”,反正一定能到达最后一个index,那么只要尽可能往后走就一定能以最少的步数到达最后的index。
- Jump Game &Jump Game II
- Jump Game/Jump Game II
- LeetCode: Jump Game II
- LeetCode Jump Game II
- LeetCode: Jump Game II
- [Leetcode] Jump Game II
- [LeetCode] Jump Game II
- [Leetcode] Jump Game ii
- leetcode Jump Game II
- Jump Game II
- Jump Game II
- Jump Game II
- leetcode Jump Game II
- [LeetCode]Jump Game II
- Jump Game II
- Jump Game II
- Jump Game II
- Jump Game II
- 关于ffmpeg的一个bug长期求解答
- Elasticsearch&logstash&filebeat&kibana&x-pack搭建
- 深入理解HashSet
- [较难] UVa OJ 12174 Shuffle 滑动窗口
- decltype详解之指针类型的推断
- Jump Game II
- 学html5不得不说的html5shiv.js和pug
- Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) A—C题解
- 【C基础】数组指针 or 指针数组???
- 密码框自动切换焦点
- 仿购物车加减数字
- Spring Boot学习
- 宏的高级使用 ----#,##,__VA_ARGS__,__FILE__,__FUNCTION
- 数组排序