zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
    〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法
    unity, dll is not allowed to be included or could not be found
    android check box 自定义图片
    unity, ios skin crash
    unity, Collider2D.bounds的一个坑
    unity, ContentSizeFitter立即生效
    类里的通用成员函数应声明为static
    unity, Gizmos.DrawMesh一个坑
    直线切割凹多边形
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14548150.html
Copyright © 2011-2022 走看看