题目大意:
已知an,从i出发的话,每次我们可以选择走去min(n,i + a[i]),或者[0,i-1],现在问我们最少几步可以走到n.
n<=1e6
解题思路:
无权最短路,优先考虑BFS,但是我们每次假如按照题意每次都往前走的话会超时复杂度n^2,那么我们可以怎么改进呢?我们发现,从i位置出发,下次走的时候枚举的起点不必要从0开始到i-1,假如之前我们已经在u点往前跳过了,那么我们应该从之前跳过的那一段的位置(即u+1)开始到i-1。这样子枚举即可。
const int inf = 1e9;
class Solution {
public:
int minJump(vector<int>& jump) {
int n = jump.size();
vector<int> dist(n+1,0);
int ls = 0;
vector<int> flag(n+1,0);
queue<int> q;
q.push(0);
flag[0] = 1;
while(!q.empty()){
int u = q.front();q.pop();
if(u == n)break;
for(int nx=ls;nx<u;nx++){
if(!flag[nx]){
flag[nx] = 1;
dist[nx] = dist[u] + 1;
q.push(nx);
}
}
ls = max(ls, u+1);
int nx = min(n,u + jump[u]);
if(!flag[nx]){
flag[nx] = 1;
dist[nx] = dist[u] + 1;
q.push(nx);
}
}
return dist[n];
}
};