1345. Jump Game IV

问题:

跳棋游戏。

在一维数组arr中,从index=0开始,

下一步可以跳到:(在数组范围内)

  • index+1
  • index-1
  • index_j : arr[index_j]=arr[index]

求最快跳到最后一格arr.size()-1的位置,需要多少步。

Example 1:
Input: arr = [100,-23,-23,404,100,23,23,23,3,404]
Output: 3
Explanation: You need three jumps from index 0 --> 4 --> 3 --> 9. Note that index 9 is the last index of the array.

Example 2:
Input: arr = [7]
Output: 0
Explanation: Start index is the last index. You don't need to jump.

Example 3:
Input: arr = [7,6,9,6,9,6,9,7]
Output: 1
Explanation: You can jump directly from index 0 to index 7 which is last index of the array.

Example 4:
Input: arr = [6,1,9]
Output: 2

Example 5:
Input: arr = [11,22,7,7,7,7,7,7,7,22,13]
Output: 3
 

Constraints:
1 <= arr.length <= 5 * 104
-108 <= arr[i] <= 108

  

解法:BFS

状态:当前index

queue中保存该状态,visited中也存该状态,来防止重复。

选择:

  • index+1
  • index-1
  • index_j : arr[index_j]=arr[index]

因此需要初始化构造index_j的所有取值。graph[arr[index]]

⚠️ 注意:本问题中数量级很大,需要考虑如何剪枝。

根据题意,如跳到 i 的位置后,下一步可选择所有 值==arr[i]的index。

这些index,其实也只能入队一次,尝试一次即可。

(由于本来queue的遍历就是按照层次从0开始,一次变大的,因此先入队的index,一定经过的步数较小

因此,可以在尝试入队一次所有的 index_j 后,直接删除相同arr[i]下的所有 index_j )。

下一次在找到相同的arr[i]值,去求 index_j 的时候,已经入队过,可以不需要入队检查。

代码参考:

 1 class Solution {
 2 public:
 3     int n;
 4     int minJumps(vector<int>& arr) {
 5         unordered_map<int, vector<int>> graph;//arr[i], {i,j,...}
 6         n = arr.size();
 7         for(int i=0; i<n; i++) {
 8             graph[arr[i]].push_back(i);
 9         }
10         unordered_set<int> visited;
11         queue<int>q;
12         int step = 0;
13         q.push(0);
14         visited.insert(0);
15         while(!q.empty()) {
16             int sz = q.size();
17             for(int k=0; k<sz; k++) {
18                 int cur = q.front();
19                 q.pop();
20                 //cout<<"pop: "<<cur<<endl;
21                 if(cur==n-1) return step;
22                 if(cur+1<n && visited.insert(cur+1).second) {
23                     //cout<<"push:cur+1: "<<cur+1<<" step:"<<step<<endl;
24                     q.push(cur+1);
25                 }
26                 if(cur-1>0 && visited.insert(cur-1).second) {
27                     //cout<<"push:cur-1: "<<cur-1<<" step:"<<step<<endl;
28                     q.push(cur-1);
29                 }
30                 for(int idx:graph[arr[cur]]) {
31                     if(visited.insert(idx).second) {
32                         //cout<<"push:idx: "<<idx<<" value:"<<arr[cur]<<" step:"<<step<<endl;
33                         q.push(idx);
34                     }
35                 }
36                 //cout<<"clear graph:"<<cur<<endl;
37                 graph[arr[cur]].clear();//相同的值对应的index都加入过,去掉。
38             }
39             step++;
40         }
41         return n;
42     }
43 };
原文地址:https://www.cnblogs.com/habibah-chang/p/14548150.html