Leetcode Algorithm 045. Jump Game II
Jump Game II
给定一个非负整数的数组,数组中的元素表示从当前位置可以跳过的最长步数;从数组的第一个位置,可以经过中途的某些点跳到最后一个位置,请找出少的跳跃次数
解题思路
与Jump Game不同,这次要找出最短的跳跃次数,也就是从A[0]出发,到达A[n-1]的最短路径(n为数组元素的个数)。
显然这是一个类图的问题。样例A=[2,3,1,1,4]
当中
- 由于A[0]=2,从0号点出发可以到达1,2号点
- 由于A[1]=3,从1号点出发可以到达2,3,4号点
- 由于A[2]=1,从2号点出发可以到达3号点
- 由于A[3]=1,从2号点出发可以到达4号点
写成邻接表就是:
0 -> [1,2]
1 -> [2,3,4]
2 -> [3]
3 -> [4]
4 -> []
很明显地,我们可以用BSF来寻找从0号点到4号点的最短路径,因为两点之间的距离可视为1。
我们可以用一个元组(index, level)
表示当前结点在BFS树中的层级情况,并用队列辅助实现BFS。
其中一个技巧是先搜索跳跃跨度较大的结点,防止超时。
代码
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
class Solution {
public:
int jump(vector<int>& nums) {
int n = nums.size();
bool visited[n] = { false };
queue<pair<int, int> > q; //(index, level)
q.push(make_pair(0, 0));
visited[0] = true;
bool found = false;
while (!q.empty() && !found) {
int front_index = q.front().first;
int front_level = q.front().second;
for (int i = nums[front_index]; i >= 0; i--) {
int index = front_index + i;
if (index < n && !visited[index]) {
q.push(make_pair(index, front_level + 1));
visited[index] = true;
// early stop
if (index == n - 1) {
found = true;
break;
}
}
}
q.pop();
}
return q.back().second;
}
};
测试样例与输出
struct TestCase {
vector<int> nums;
};
int main() {
int numTestCase = 2;
TestCase tCase[numTestCase];
int arr0[] = { 2, 3, 1, 1, 4 };
tCase[0].nums.assign(arr0, arr0 + 5);
int arr1[] = { 2, 2, 1, 1, 4 };
tCase[1].nums.assign(arr1, arr1 + 5);
Solution s;
for (int t = 0; t < numTestCase; t++) {
cout << s.jump(tCase[t].nums) << endl;
}
return 0;
}
输出
2
3