📌  相关文章
📜  获得相反奇偶校验元素的最少跳转次数

📅  最后修改于: 2021-09-05 11:41:57             🧑  作者: Mango

给定由N 个正整数组成的两个数组arr[]jumps[] ,每个数组元素arr[i]的任务是找到到达相反奇偶校验元素所需的最小跳转次数。从任何数组元素arr[i]唯一可能的跳转是(i + jumps[i])(i – jumps[i])

例子:

朴素的方法:解决问题最简单的方法是遍历数组并对每个数组元素arr[i]进行广度优先遍历,通过反复转换为arr[i – jumps[i]]arr[i + jumps [i]] ,直到出现任何无效索引,并且在每次转换后,检查数组元素是否与前一个元素具有相反的奇偶校验。相应地打印每个数组元素所需的最小跳转次数。

时间复杂度: O(N 2 )
辅助空间: O(N)

高效的方法:为了优化上述方法,想法是分别对偶数和奇数数组元素使用多源 BFS。请按照以下步骤解决问题:

  1. 初始化一个向量,比如ans[] ,以存储每个数组元素到达相反奇偶校验的元素所需的最小跳跃。
  2. 初始化向量数组Adj[]来存储生成的图的邻接表。
  3. 对于每个索引的每一对(i, j)有效跳转,数组的i通过将边初始化为(j, i) 来创建一个倒置图。
  4. 对奇数元素执行多源 BFS 遍历。执行以下步骤:
    • 将包含奇数数组元素的所有索引推送到队列中,并将所有这些节点标记为同时访问。
    • 迭代直到队列非空并执行以下操作:
      • 弹出出现在队列前面的节点并检查它现在连接到它的任何节点是否具有相同的奇偶校验。如果发现为真,则将子节点距离更新为1 + 父节点的距离。
      • 标记访问过的子节点并将其推入队列。
  5. 类似地对偶数元素执行多源 BFS 遍历并将距离存储在ans[] 中
  6. 完成上述步骤后,打印ans[] 中存储的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Bfs for odd numbers are source
void bfs(int n, vector& a,
         vector invGr[],
         vector& ans, int parity)
{
    // Initialize queue
    queue q;
 
    // Stores for each node, the nodes
    // visited and their distances
    vector vis(n + 1, 0);
    vector dist(n + 1, 0);
 
    // Push odd and even numbers
    // as sources to the queue
 
    // If parity is 0 -> odd
    // Otherwise -> even
    for (int i = 1; i <= n; i++) {
        if ((a[i] + parity) & 1) {
            q.push(i);
            vis[i] = 1;
        }
    }
 
    // Peform multi-source bfs
    while (!q.empty()) {
 
        // Extract the front element
        // of the queue
        int v = q.front();
        q.pop();
 
        // Traverse nodes connected
        // to the current node
        for (int u : invGr[v]) {
 
            // If u is not visited
            if (!vis[u]) {
 
                dist[u] = dist[v] + 1;
                vis[u] = 1;
 
                // If element with opposite
                // parity is obtained
                if ((a[u] + parity) % 2 == 0) {
                    if (ans[u] == -1)
 
                        // Store its distance from
                        // source in ans[]
                        ans[u] = dist[u];
                }
 
                // Push the current neighbour
                // to the queue
                q.push(u);
            }
        }
    }
}
 
// Function to find the minimum jumps
// required by each index to reach
// element of opposite parity
void minJumps(vector& a,
              vector& jump, int n)
{
    // Initialise Inverse Graph
    vector invGr[n + 1];
 
    // Stores the result for each index
    vector ans(n + 1, -1);
 
    for (int i = 1; i <= n; i++) {
 
        // For the jumped index
        for (int ind : { i + jump[i],
                         i - jump[i] }) {
 
            // If the ind is valid then
            // add reverse directed edge
            if (ind >= 1 and ind <= n) {
                invGr[ind].push_back(i);
            }
        }
    }
 
    // Multi-source bfs with odd
    // numbers as source by passing 0
    bfs(n, a, invGr, ans, 0);
 
    // Multi-source bfs with even
    // numbers as source by passing 1
    bfs(n, a, invGr, ans, 1);
 
    // Print the answer
    for (int i = 1; i <= n; i++) {
        cout << ans[i] << ' ';
    }
}
 
// Driver Code
int main()
{
    vector arr = { 0, 4, 2, 5, 2, 1 };
    vector jump = { 0, 1, 2, 3, 1, 2 };
 
    int N = arr.size();
 
    minJumps(arr, jump, N - 1);
 
    return 0;
}


Java
// Java program for above approach
import java.util.*;
import java.lang.*;
 
class Gfg
{
 
  // Bfs for odd numbers are source
  static void bfs(int n, int[] a,
                  ArrayList> invGr,
                  int[] ans, int parity)
  {
 
    // Initialize queue
    Queue q = new LinkedList<>();
 
    // Stores for each node, the nodes
    // visited and their distances
    int[] vis = new int[n + 1];
    int[] dist = new int[n + 1];
 
    // Push odd and even numbers
    // as sources to the queue
 
    // If parity is 0 -> odd
    // Otherwise -> even
    for (int i = 1; i <= n; i++) {
      if (((a[i] + parity) & 1) != 0) {
        q.add(i);
        vis[i] = 1;
      }
    }
 
    // Peform multi-source bfs
    while (!q.isEmpty()) {
 
      // Extract the front element
      // of the queue
      int v = q.peek();
      q.poll();
 
      // Traverse nodes connected
      // to the current node
      for (Integer u : invGr.get(v)) {
 
        // If u is not visited
        if (vis[u] == 0) {
 
          dist[u] = dist[v] + 1;
          vis[u] = 1;
 
          // If element with opposite
          // parity is obtained
          if ((a[u] + parity) % 2 == 0) {
            if (ans[u] == -1)
 
              // Store its distance from
              // source in ans[]
              ans[u] = dist[u];
          }
 
          // Push the current neighbour
          // to the queue
          q.add(u);
        }
      }
    }
  }
 
  // Function to find the minimum jumps
  // required by each index to reach
  // element of opposite parity
  static void minJumps(int[] a,
                       int[] jump, int n)
  {
 
    // Initialise Inverse Graph
    ArrayList> invGr = new ArrayList<>();
 
    for(int i = 0; i <= n; i++)
      invGr.add(new ArrayList());
 
    // Stores the result for each index
    int[] ans = new int[n + 1];
    Arrays.fill(ans, -1);
 
    for (int i = 1; i <= n; i++)
    {
 
      // For the jumped index
      // If the ind is valid then
      // add reverse directed edge
      if (i+ jump[i] >= 1 && i+jump[i] <= n) {
        invGr.get(i+ jump[i]).add(i);
      }
      if (i-jump[i] >= 1 && i-jump[i] <= n) {
        invGr.get(i- jump[i]).add(i);
      }
    }
 
    // Multi-source bfs with odd
    // numbers as source by passing 0
    bfs(n, a, invGr, ans, 0);
 
    // Multi-source bfs with even
    // numbers as source by passing 1
    bfs(n, a, invGr, ans, 1);
 
    // Print the answer
    for (int i = 1; i <= n; i++)
    {
      System.out.print(ans[i] + " ");
    }
  }
 
  // Driver function
  public static void main (String[] args)
  {
    int[] arr = { 0, 4, 2, 5, 2, 1 };
    int[] jump = { 0, 1, 2, 3, 1, 2 };
 
    int N = arr.length;
 
    minJumps(arr, jump, N - 1);
  }
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
  
# Bfs for odd numbers are source
def bfs(n, a, invGr, ans, parity):
     
    # Initialize queue
    q = []
     
    # Stores for each node, the nodes
    # visited and their distances
    vis = [0 for i in range(n + 1)]
    dist = [0 for i in range(n + 1)]
  
    # Push odd and even numbers
    # as sources to the queue
  
    # If parity is 0 -> odd
    # Otherwise -> even
    for i in range(1, n + 1):
        if ((a[i] + parity) & 1):
            q.append(i)
            vis[i] = 1
             
    # Peform multi-source bfs
    while (len(q) != 0):
         
        # Extract the front element
        # of the queue
        v = q[0]
        q.pop(0)
  
        # Traverse nodes connected
        # to the current node
        for u in invGr[v]:
  
            # If u is not visited
            if (not vis[u]):
                dist[u] = dist[v] + 1
                vis[u] = 1
  
                # If element with opposite
                # parity is obtained
                if ((a[u] + parity) % 2 == 0):
                    if (ans[u] == -1):
  
                        # Store its distance from
                        # source in ans[]
                        ans[u] = dist[u]
  
                # Push the current neighbour
                # to the queue
                q.append(u)
  
# Function to find the minimum jumps
# required by each index to reach
# element of opposite parity
def minJumps(a, jump, n):
 
    # Initialise Inverse Graph
    invGr = [[] for i in range(n + 1)]
  
    # Stores the result for each index
    ans = [-1 for i in range(n + 1)]
     
    for i in range(1, n + 1):
  
        # For the jumped index
        for ind in [i + jump[i], i - jump[i]]:
  
            # If the ind is valid then
            # add reverse directed edge
            if (ind >= 1 and ind <= n):
                invGr[ind].append(i)
  
    # Multi-source bfs with odd
    # numbers as source by passing 0
    bfs(n, a, invGr, ans, 0)
  
    # Multi-source bfs with even
    # numbers as source by passing 1
    bfs(n, a, invGr, ans, 1)
  
    # Print the answer
    for i in range(1, n + 1):
        print(str(ans[i]), end = ' ')
         
# Driver Code
if __name__=='__main__':
     
    arr = [ 0, 4, 2, 5, 2, 1 ]
    jump = [ 0, 1, 2, 3, 1, 2 ]
  
    N = len(arr)
  
    minJumps(arr, jump, N - 1)
     
# This code is contributed by pratham76


输出:
3 2 -1 1 -1

时间复杂度: O(N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live