Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to detect cycles in 2D grid in Python
Cycle detection in a 2D grid is a common graph problem where we need to find if there exists a path that starts and ends at the same cell. A cycle must have at least 4 cells and we can only move to adjacent cells with the same character value.
Problem Understanding
Given a 2D grid of characters, we need to detect if there's a cycle. The conditions are ?
A cycle has length 4 or more
We can move in four directions (up, down, left, right)
Adjacent cells must have the same character
Cannot revisit cells except the starting cell to complete the cycle
Example Grid
| m | m | m | p |
| m | k | m | m |
| m | m | s | m |
| f | t | m | m |
The green cells form a cycle, so the output should be True.
Algorithm Approach
We use DFS with three-color marking ?
WHITE (0): Unvisited cell
GRAY (1): Currently being processed
BLACK (2): Completely processed
Implementation
from collections import defaultdict
def detect_cycle_in_grid(grid):
WHITE, GRAY, BLACK = 0, 1, 2
R, C = len(grid), len(grid[0])
# Color mapping for each cell
color = defaultdict(int)
# Direction vectors: up, right, down, left
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
def dfs(r, c, parent_r=-1, parent_c=-1):
color[r, c] = GRAY
for dx, dy in directions:
nr, nc = r + dx, c + dy
# Check bounds and same character
if (0 <= nr < R and 0 <= nc < C and
grid[r][c] == grid[nr][nc] and
(nr, nc) != (parent_r, parent_c)):
if color[nr, nc] == WHITE:
if dfs(nr, nc, r, c):
return True
elif color[nr, nc] == GRAY:
# Found back edge - cycle detected
return True
color[r, c] = BLACK
return False
# Check each unvisited cell
for r in range(R):
for c in range(C):
if color[r, c] == WHITE:
if dfs(r, c):
return True
return False
# Test with the example grid
grid = [
["m", "m", "m", "p"],
["m", "k", "m", "m"],
["m", "m", "s", "m"],
["f", "t", "m", "m"]
]
print(detect_cycle_in_grid(grid))
True
How It Works
The algorithm performs DFS from each unvisited cell ?
Mark as GRAY: When visiting a cell, mark it as currently being processed
Explore neighbors: Check all 4 adjacent cells with the same character
Skip parent: Avoid going back to the immediate parent cell
Detect cycle: If we reach a GRAY cell, we found a back edge (cycle)
Mark as BLACK: After processing all neighbors, mark as completed
Test with Different Grid
# Grid without cycle
grid_no_cycle = [
["a", "a", "b"],
["a", "b", "b"],
["b", "b", "a"]
]
print("Grid without cycle:", detect_cycle_in_grid(grid_no_cycle))
# Grid with cycle
grid_with_cycle = [
["a", "a", "a"],
["a", "b", "a"],
["a", "a", "a"]
]
print("Grid with cycle:", detect_cycle_in_grid(grid_with_cycle))
Grid without cycle: False Grid with cycle: True
Time and Space Complexity
Time Complexity: O(m × n) where m and n are grid dimensions
Space Complexity: O(m × n) for the color mapping and recursion stack
Conclusion
This DFS-based approach efficiently detects cycles in 2D grids using three-color marking. The key insight is treating the grid as a graph where edges connect adjacent cells with the same character, then detecting back edges during traversal.
