Given a 2D array of characters grid
of size m x n
, you need to find if there exists any cycle consisting of the same value in grid
.
A cycle is a path of length 4 or more in the grid that starts and ends at the same cell. From a given cell, you can move to one of the cells adjacent to it - in one of the four directions (up, down, left, or right), if it has the same value of the current cell.
Also, you cannot move to the cell that you visited in your last move. For example, the cycle (1, 1) -> (1, 2) -> (1, 1)
is invalid because from (1, 2)
we visited (1, 1)
which was the last visited cell.
Return true
if any cycle of the same value exists in grid
, otherwise, return false
.
Example 1:
Input: grid = [["a","a","a","a"],["a","b","b","a"],["a","b","b","a"],["a","a","a","a"]] Output: true Explanation: There are two valid cycles shown in different colors in the image below:![]()
Example 2:
Input: grid = [["c","c","c","a"],["c","d","c","c"],["c","c","e","c"],["f","c","c","c"]] Output: true Explanation: There is only one valid cycle highlighted in the image below:![]()
Example 3:
Input: grid = [["a","b","b"],["b","z","b"],["b","b","a"]] Output: false
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 500
grid
consists only of lowercase English letters.Given an m x n
grid of characters, determine if there exists a cycle consisting of the same character. A cycle is a path of length 4 or more that starts and ends at the same cell, moving only to adjacent cells with the same character value, and avoiding immediate backtracking.
The most efficient approach to solve this problem is using Depth-First Search (DFS). We'll iterate through each cell of the grid. If a cell hasn't been visited, we initiate a DFS from that cell.
The DFS function needs to track:
(x, y)
(px, py)
(to prevent immediate backtracking)vis
to mark visited cells.During the DFS:
true
.false
.After iterating through all cells and performing DFS where necessary, if no cycle is found, the function returns false
.
def containsCycle(grid):
m, n = len(grid), len(grid[0])
vis = [[False] * n for _ in range(m)]
dirs = [(0, 1), (0, -1), (1, 0), (-1, 0)] # Directions: Right, Left, Down, Up
def dfs(x, y, px, py):
vis[x][y] = True
for dx, dy in dirs:
nx, ny = x + dx, y + dy
if 0 <= nx < m and 0 <= ny < n:
if grid[nx][ny] == grid[x][y] and (nx != px or ny != py):
if vis[nx][ny]:
return True
if dfs(nx, ny, x, y):
return True
return False
for i in range(m):
for j in range(n):
if not vis[i][j]:
if dfs(i, j, -1, -1):
return True
return False
vis
array used for tracking visited cells. The recursion depth in the worst case is also proportional to m * n
.The solution can be implemented similarly in other languages like Java, C++, JavaScript, etc., with minor syntactic differences. The core logic of DFS with visited cell tracking remains the same. The key is to correctly manage the visited array and the traversal directions to avoid unnecessary computations.