📌  相关文章
📜  根据给定约束在数组中形成循环的元素计数

📅  最后修改于: 2021-05-04 21:11:31             🧑  作者: Mango

给定一个包含N个整数的数组A ,任务是根据以下条件计算组成数组中一个循环的元素数。
开始从索引i遍历Array,并跳转到下一个连接的索引。如果j = GCD(i,A [i])%N,则有向边从A的索引i退出到索引j 。如果以所描述的顺序遍历数组,则再次访问索引i,然后称索引i在数组中形成一个循环。
例子:

方法:
为了解决上述问题,我们必须假设每个索引代表图的单个节点

  • 如果j = GCD(i,A [i])%n,则每个节点都有一个从A的索引i到索引j的有向边。如果遍历从节点i开始。
  • 节点i将被称为该遍历的父节点,并且该父节点将被分配给遍历过程中访问的所有节点。
  • 在遍历图形时,如果我们发现一个已经访问过的节点,并且该访问的节点的父节点与遍历的父节点相同,则将检测到一个新的周期。
  • 现在,将在此循环中的每个节点都形成循环时对其进行计数。要计算此循环中的节点数,请从该节点启动另一个DFS,直到不再访问同一节点为止。
  • 对图的每个节点i重复此过程。

在最坏的情况下,每个节点最多将遍历3次。因此,解决方案具有线性时间复杂度。

下面是上述方法的实现:

C++
// C++ program to number of elements 
// which form a cycle in an array 
  
#include  
using namespace std; 
  
#define mp make_pair 
#define pb push_back 
#define mod 1000000007 
  
// Function to count number of 
// elements forming a cycle 
int solve(int A[], int n) 
{ 
    int i, cnt = 0, j; 
  
    // Array to store parent 
    // node of traversal. 
    int parent[n]; 
  
    // Array to determine 
    // whether current node 
    // is already counted 
    // in the cycle. 
    int vis[n]; 
  
    // Initialize the arrays. 
    memset(parent, -1, sizeof(parent)); 
    memset(vis, 0, sizeof(vis)); 
  
    for (i = 0; i < n; i++) { 
        j = i; 
  
        // Check if current node is already 
        // traversed or not. If node is not 
        // traversed yet then parent value 
        // will be -1. 
        if (parent[j] == -1) { 
  
            // Traverse the graph until an 
            // already visited node is not 
            // found. 
            while (parent[j] == -1) { 
                parent[j] = i; 
                j = __gcd(j, A[j]) % n; 
            } 
  
            // Check parent value to ensure 
            // a cycle is present. 
            if (parent[j] == i) { 
  
                // Count number of nodes in 
                // the cycle. 
                while (!vis[j]) { 
                    vis[j] = 1; 
                    cnt++; 
                    j = __gcd(j, A[j]) % n; 
                } 
            } 
        } 
    } 
  
    return cnt; 
} 
  
int main() 
{ 
    int A[] = { 1, 1, 6, 2 }; 
    int n = sizeof(A) / sizeof(A[0]); 
    cout << solve(A, n); 
    return 0; 
}


Java
// Java program to number of elements 
// which form a cycle in an array 
import java.util.*; 
class GFG{ 
  
static final int mod = 1000000007; 
  
// Function to count number of 
// elements forming a cycle 
static int solve(int A[], int n) 
{ 
    int i, cnt = 0, j; 
  
    // Array to store parent 
    // node of traversal. 
    int []parent = new int[n]; 
  
    // Array to determine 
    // whether current node 
    // is already counted 
    // in the cycle. 
    int []vis = new int[n]; 
  
    // Initialize the arrays. 
    Arrays.fill(parent, -1); 
    Arrays.fill(vis, 0); 
  
    for(i = 0; i < n; i++) 
    { 
        j = i; 
  
        // Check if current node is already 
        // traversed or not. If node is not 
        // traversed yet then parent value 
        // will be -1. 
        if (parent[j] == -1) 
        { 
  
            // Traverse the graph until an 
            // already visited node is not 
            // found. 
            while (parent[j] == -1) 
            { 
                parent[j] = i; 
                j = __gcd(j, A[j]) % n; 
            } 
  
            // Check parent value to ensure 
            // a cycle is present. 
            if (parent[j] == i) 
            { 
  
                // Count number of nodes in 
                // the cycle. 
                while (vis[j] == 0) 
                { 
                    vis[j] = 1; 
                    cnt++; 
                    j = __gcd(j, A[j]) % n; 
                } 
            } 
        } 
    } 
    return cnt; 
} 
  
static int __gcd(int a, int b) 
{ 
    return b == 0 ? a : __gcd(b, a % b);     
} 
  
// Driver code 
public static void main(String[] args) 
{ 
    int A[] = { 1, 1, 6, 2 }; 
    int n = A.length; 
      
    System.out.print(solve(A, n)); 
} 
} 
  
// This code is contributed by gauravrajput1


Python3
# Python3 program to number of elements 
# which form a cycle in an array 
import math 
  
mod = 1000000007
  
# Function to count number of 
# elements forming a cycle 
def solve(A, n): 
      
    cnt = 0
  
    # Array to store parent 
    # node of traversal. 
    parent = [-1] * n 
  
    # Array to determine 
    # whether current node 
    # is already counted 
    # in the cycle. 
    vis = [0] * n 
  
    for i in range(n): 
        j = i 
  
        # Check if current node is already 
        # traversed or not. If node is not 
        # traversed yet then parent value 
        # will be -1. 
        if (parent[j] == -1): 
  
            # Traverse the graph until an 
            # already visited node is not 
            # found. 
            while (parent[j] == -1): 
                parent[j] = i 
                j = math.gcd(j, A[j]) % n 
              
            # Check parent value to ensure 
            # a cycle is present. 
            if (parent[j] == i): 
  
                # Count number of nodes in 
                # the cycle. 
                while (vis[j] == 0): 
                    vis[j] = 1
                    cnt += 1
                    j = math.gcd(j, A[j]) % n 
                      
    return cnt 
  
# Driver code 
A = [ 1, 1, 6, 2 ] 
n = len(A) 
  
print(solve(A, n)) 
  
# This code is contributed by sanjoy_62


C#
// C# program to number of elements 
// which form a cycle in an array 
using System;
  
class GFG{
      
// Function to count number of 
// elements forming a cycle 
static int solve(int[] A, int n) 
{ 
    int i, cnt = 0, j; 
  
    // Array to store parent 
    // node of traversal. 
    int[] parent = new int[n]; 
  
    // Array to determine 
    // whether current node 
    // is already counted 
    // in the cycle. 
    int[] vis = new int[n]; 
  
    // Initialize the arrays. 
    Array.Fill(parent, -1); 
    Array.Fill(vis, 0); 
  
    for(i = 0; i < n; i++) 
    { 
        j = i; 
  
        // Check if current node is already 
        // traversed or not. If node is not 
        // traversed yet then parent value 
        // will be -1. 
        if (parent[j] == -1) 
        { 
              
            // Traverse the graph until an 
            // already visited node is not 
            // found. 
            while (parent[j] == -1) 
            { 
                parent[j] = i; 
                j = __gcd(j, A[j]) % n; 
            } 
  
            // Check parent value to ensure 
            // a cycle is present. 
            if (parent[j] == i) 
            { 
  
                // Count number of nodes in 
                // the cycle. 
                while (vis[j] == 0) 
                { 
                    vis[j] = 1; 
                    cnt++; 
                    j = __gcd(j, A[j]) % n; 
                } 
            } 
        } 
    } 
    return cnt; 
} 
  
static int __gcd(int a, int b) 
{ 
    return b == 0 ? a : __gcd(b, a % b);     
}
  
// Driver code
static void Main() 
{
    int[] A = { 1, 1, 6, 2 }; 
    int n = A.Length; 
      
    Console.WriteLine(solve(A, n));
}
}
  
// This code is contributed by divyeshrabadiya07


输出:
2

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