根据给定的约束检查数组中的循环
给定一个由正数和负数组成的数组 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