📜  根据给定的约束检查数组中的循环

📅  最后修改于: 2022-05-13 01:57:49.524000             🧑  作者: Mango

根据给定的约束检查数组中的循环

给定一个由正数和负数组成的数组 arr[0..n-1],我们需要找出数组中是否存在具有给定运动规则的循环。如果第 i 个索引处的数字为正,则将 arr[i]%n 向前移动,即下一个要访问的索引是 (i + arr[i])%n。相反,如果它是负数,则向后移动 arr[i]%n 步,即,下一个要访问的索引是 (i – arr[i])%n。这里 n 是数组的大小。如果 arr[i]%n 的值为零,则意味着没有从索引 i 移动。
例子:

Input: arr[] = {2, -1, 1, 2, 2}
Output: Yes
Explanation: There is a loop in this array
because 0 moves to 2, 2 moves to 3, and 3 
moves to 0.

Input  : arr[] = {1, 1, 1, 1, 1, 1}
Output : Yes
Whole array forms a loop.

Input  : arr[] = {1, 2}
Output : No
We move from 0 to index 1. From index
1, there is no move as 2%n is 0. Note that
n is 2.

请注意,自循环不被视为循环。例如 {0} 不是循环的。

这个想法是使用给定的规则集形成数组元素的有向图。在形成图表时,我们不会进行自循环,因为值 arr[i]%n 等于 0 意味着没有移动。最后,我们的任务简化为在有向图中检测循环。为了检测循环,我们使用 DFS,在 DFS 中,如果到达一个被访问的节点和递归调用堆栈,我们就说有一个循环。

C++
// C++ program to check if a given array is cyclic or not
#include
using namespace std;
 
// A simple Graph DFS based recursive function to check if
// there is cycle in graph with vertex v as root of DFS.
// Refer below article for details.
// https://www.geeksforgeeks.org/detect-cycle-in-a-graph/
bool isCycleRec(int v, vectoradj[],
               vector &visited, vector &recur)
{
    visited[v] = true;
    recur[v] = true;
    for (int i=0; iadj[n];
    for (int i=0; i visited(n, false);
    vector recur(n, false);
    for (int i=0; i


Java
// Java program to check if
// a given array is cyclic or not
import java.util.Vector;
 
class GFG
{
 
    // A simple Graph DFS based recursive function
    // to check if there is cycle in graph with
    // vertex v as root of DFS. Refer below article for details.
    // https://www.geeksforgeeks.org/detect-cycle-in-a-graph/
    static boolean isCycleRec(int v, Vector[] adj,
                                     Vector visited,
                                     Vector recur)
    {
        visited.set(v, true);
        recur.set(v, true);
 
        for (int i = 0; i < adj[v].size(); i++)
        {
            if (visited.elementAt(adj[v].elementAt(i)) == false)
            {
                if (isCycleRec(adj[v].elementAt(i),
                               adj, visited, recur))
                    return true;
            }
 
            // There is a cycle if an adjacent is visited
            // and present in recursion call stack recur[]
            else if (visited.elementAt(adj[v].elementAt(i)) == true &&
                       recur.elementAt(adj[v].elementAt(i)) == true)
                return true;
        }
        recur.set(v, false);
        return false;
    }
 
    // Returns true if arr[] has cycle
    @SuppressWarnings("unchecked")
    static boolean isCycle(int[] arr, int n)
    {
 
        // Create a graph using given moves in arr[]
        Vector[] adj = new Vector[n];
        for (int i = 0; i < n; i++)
            if (i != (i + arr[i] + n) % n &&
                          adj[i] != null)
                adj[i].add((i + arr[i] + n) % n);
 
        // Do DFS traversal of graph to detect cycle
        Vector visited = new Vector<>();
        for (int i = 0; i < n; i++)
            visited.add(true);
        Vector recur = new Vector<>();
        for (int i = 0; i < n; i++)
            recur.add(true);
 
        for (int i = 0; i < n; i++)
            if (visited.elementAt(i) == false)
                if (isCycleRec(i, adj, visited, recur))
                    return true;
        return true;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 2, -1, 1, 2, 2 };
        int n = arr.length;
        if (isCycle(arr, n) == true)
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
 
// This code is contributed by sanjeev2552


Python3
# Python3 program to check if a
# given array is cyclic or not
 
# A simple Graph DFS based recursive
# function to check if there is cycle
# in graph with vertex v as root of DFS.
# Refer below article for details.
# https:#www.geeksforgeeks.org/detect-cycle-in-a-graph/
def isCycleRec(v, adj, visited, recur):
    visited[v] = True
    recur[v] = True
    for i in range(len(adj[v])):
        if (visited[adj[v][i]] == False):
            if (isCycleRec(adj[v][i], adj,
                               visited, recur)):
                return True
 
        # There is a cycle if an adjacent is visited
        # and present in recursion call stack recur[]
        else if (visited[adj[v][i]] == True and
                recur[adj[v][i]] == True):
            return True
 
    recur[v] = False
    return False
 
# Returns true if arr[] has cycle
def isCycle(arr, n):
     
    # Create a graph using given
    # moves in arr[]
    adj = [[] for i in range(n)]
    for i in range(n):
        if (i != (i + arr[i] + n) % n):
            adj[i].append((i + arr[i] + n) % n)
 
    # Do DFS traversal of graph
    # to detect cycle  
    visited = [False] * n
    recur = [False] * n
    for i in range(n):
        if (visited[i] == False):
            if (isCycleRec(i, adj,
                           visited, recur)):
                return True
    return True
 
# Driver code
if __name__ == '__main__':
 
    arr = [2, -1, 1, 2, 2]
    n = len(arr)
    if (isCycle(arr, n)):
        print("Yes")
    else:
        print("No")
 
# This code is contributed by PranchalK


C#
// C# program to check if
// a given array is cyclic or not
using System;
using System.Collections.Generic;
public class GFG
{
 
  // A simple Graph DFS based recursive function
  // to check if there is cycle in graph with
  // vertex v as root of DFS. Refer below article for details.
  // https://www.geeksforgeeks.org/detect-cycle-in-a-graph/
  static bool isCycleRec(int v, List[] adj,
                         List visited,
                         List recur)
  {
    visited[v] = true;
    recur[v] =  true;
 
    for (int i = 0; i < adj[v].Count; i++)
    {
      if (visited[adj[v][i]] == false)
      {
        if (isCycleRec(adj[v][i],
                       adj, visited, recur))
          return true;
      }
 
      // There is a cycle if an adjacent is visited
      // and present in recursion call stack recur[]
      else if (visited[adj[v][i]] == true &&
               recur[adj[v][i]] == true)
        return true;
    }
    recur[v] = false;
    return false;
  }
 
  // Returns true if []arr has cycle
  static bool isCycle(int[] arr, int n)
  {
 
    // Create a graph using given moves in []arr
    List[] adj = new List[n];
    for (int i = 0; i < n; i++)
      if (i != (i + arr[i] + n) % n &&
          adj[i] != null)
        adj[i].Add((i + arr[i] + n) % n);
 
    // Do DFS traversal of graph to detect cycle
    List visited = new List();
    for (int i = 0; i < n; i++)
      visited.Add(true);
    List recur = new List();
    for (int i = 0; i < n; i++)
      recur.Add(true);
 
    for (int i = 0; i < n; i++)
      if (visited[i] == false)
        if (isCycleRec(i, adj, visited, recur))
          return true;
    return true;
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int[] arr = { 2, -1, 1, 2, 2 };
    int n = arr.Length;
    if (isCycle(arr, n) == true)
      Console.WriteLine("Yes");
    else
      Console.WriteLine("No");
  }
}
 
// This code is contributed by aashish1995


Javascript


输出:

Yes