📌  相关文章
📜  获得相等奇偶性元素的最小跳转数

📅  最后修改于: 2021-04-27 19:49:33             🧑  作者: Mango

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

例子:

天真的方法:最简单的方法是解决问题,方法是遍历数组并通过重复转换为arr [i – jumps [i]]arr [i + jumps ]对每个数组元素arr [i]执行广度优先遍历[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)