Skip to content

Commit 8ffb89d

Browse files
authored
feat: add solutions to lc problem: No.1559 (doocs#3558)
No.1559.Detect Cycles in 2D Grid
1 parent 420ec5e commit 8ffb89d

File tree

15 files changed

+1263
-455
lines changed

15 files changed

+1263
-455
lines changed

solution/1500-1599/1559.Detect Cycles in 2D Grid/README.md

Lines changed: 422 additions & 135 deletions
Large diffs are not rendered by default.

solution/1500-1599/1559.Detect Cycles in 2D Grid/README_EN.md

Lines changed: 422 additions & 135 deletions
Large diffs are not rendered by default.
Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
1-
class Solution {
2-
public:
3-
vector<int> p;
4-
5-
bool containsCycle(vector<vector<char>>& grid) {
6-
int m = grid.size(), n = grid[0].size();
7-
p.resize(m * n);
8-
for (int i = 0; i < p.size(); ++i) p[i] = i;
9-
vector<int> dirs = {0, 1, 0};
10-
for (int i = 0; i < m; ++i) {
11-
for (int j = 0; j < n; ++j) {
12-
for (int k = 0; k < 2; ++k) {
13-
int x = i + dirs[k], y = j + dirs[k + 1];
14-
if (x < m && y < n && grid[x][y] == grid[i][j]) {
15-
if (find(x * n + y) == find(i * n + j)) return 1;
16-
p[find(x * n + y)] = find(i * n + j);
17-
}
18-
}
19-
}
20-
}
21-
return 0;
22-
}
23-
24-
int find(int x) {
25-
if (p[x] != x) p[x] = find(p[x]);
26-
return p[x];
27-
}
28-
};
1+
class Solution {
2+
public:
3+
bool containsCycle(vector<vector<char>>& grid) {
4+
int m = grid.size(), n = grid[0].size();
5+
vector<vector<bool>> vis(m, vector<bool>(n));
6+
const vector<int> dirs = {-1, 0, 1, 0, -1};
7+
8+
for (int i = 0; i < m; ++i) {
9+
for (int j = 0; j < n; ++j) {
10+
if (!vis[i][j]) {
11+
queue<array<int, 4>> q;
12+
q.push({i, j, -1, -1});
13+
vis[i][j] = true;
14+
15+
while (!q.empty()) {
16+
auto p = q.front();
17+
q.pop();
18+
int x = p[0], y = p[1], px = p[2], py = p[3];
19+
20+
for (int k = 0; k < 4; ++k) {
21+
int nx = x + dirs[k], ny = y + dirs[k + 1];
22+
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
23+
if (grid[nx][ny] != grid[x][y] || (nx == px && ny == py)) {
24+
continue;
25+
}
26+
if (vis[nx][ny]) {
27+
return true;
28+
}
29+
q.push({nx, ny, x, y});
30+
vis[nx][ny] = true;
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}
37+
return false;
38+
}
39+
};
Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
1-
func containsCycle(grid [][]byte) bool {
2-
m, n := len(grid), len(grid[0])
3-
p := make([]int, m*n)
4-
for i := range p {
5-
p[i] = i
6-
}
7-
var find func(x int) int
8-
find = func(x int) int {
9-
if p[x] != x {
10-
p[x] = find(p[x])
11-
}
12-
return p[x]
13-
}
14-
dirs := []int{1, 0, 1}
15-
for i := 0; i < m; i++ {
16-
for j := 0; j < n; j++ {
17-
for k := 0; k < 2; k++ {
18-
x, y := i+dirs[k], j+dirs[k+1]
19-
if x < m && y < n && grid[x][y] == grid[i][j] {
20-
if find(x*n+y) == find(i*n+j) {
21-
return true
22-
}
23-
p[find(x*n+y)] = find(i*n + j)
24-
}
25-
}
26-
}
27-
}
28-
return false
29-
}
1+
func containsCycle(grid [][]byte) bool {
2+
m, n := len(grid), len(grid[0])
3+
vis := make([][]bool, m)
4+
for i := range vis {
5+
vis[i] = make([]bool, n)
6+
}
7+
dirs := []int{-1, 0, 1, 0, -1}
8+
9+
for i := 0; i < m; i++ {
10+
for j := 0; j < n; j++ {
11+
if !vis[i][j] {
12+
q := [][]int{{i, j, -1, -1}}
13+
vis[i][j] = true
14+
15+
for len(q) > 0 {
16+
p := q[0]
17+
q = q[1:]
18+
x, y, px, py := p[0], p[1], p[2], p[3]
19+
20+
for k := 0; k < 4; k++ {
21+
nx, ny := x+dirs[k], y+dirs[k+1]
22+
if nx >= 0 && nx < m && ny >= 0 && ny < n {
23+
if grid[nx][ny] != grid[x][y] || (nx == px && ny == py) {
24+
continue
25+
}
26+
if vis[nx][ny] {
27+
return true
28+
}
29+
q = append(q, []int{nx, ny, x, y})
30+
vis[nx][ny] = true
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}
37+
return false
38+
}
Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
1-
class Solution {
2-
private int[] p;
3-
4-
public boolean containsCycle(char[][] grid) {
5-
int m = grid.length;
6-
int n = grid[0].length;
7-
p = new int[m * n];
8-
for (int i = 0; i < p.length; ++i) {
9-
p[i] = i;
10-
}
11-
int[] dirs = {0, 1, 0};
12-
for (int i = 0; i < m; ++i) {
13-
for (int j = 0; j < n; ++j) {
14-
for (int k = 0; k < 2; ++k) {
15-
int x = i + dirs[k];
16-
int y = j + dirs[k + 1];
17-
if (x < m && y < n && grid[i][j] == grid[x][y]) {
18-
if (find(x * n + y) == find(i * n + j)) {
19-
return true;
20-
}
21-
p[find(x * n + y)] = find(i * n + j);
22-
}
23-
}
24-
}
25-
}
26-
return false;
27-
}
28-
29-
private int find(int x) {
30-
if (p[x] != x) {
31-
p[x] = find(p[x]);
32-
}
33-
return p[x];
34-
}
35-
}
1+
class Solution {
2+
public boolean containsCycle(char[][] grid) {
3+
int m = grid.length, n = grid[0].length;
4+
boolean[][] vis = new boolean[m][n];
5+
final int[] dirs = {-1, 0, 1, 0, -1};
6+
for (int i = 0; i < m; ++i) {
7+
for (int j = 0; j < n; ++j) {
8+
if (!vis[i][j]) {
9+
Deque<int[]> q = new ArrayDeque<>();
10+
q.offer(new int[] {i, j, -1, -1});
11+
vis[i][j] = true;
12+
while (!q.isEmpty()) {
13+
int[] p = q.poll();
14+
int x = p[0], y = p[1], px = p[2], py = p[3];
15+
for (int k = 0; k < 4; ++k) {
16+
int nx = x + dirs[k], ny = y + dirs[k + 1];
17+
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
18+
if (grid[nx][ny] != grid[x][y] || (nx == px && ny == py)) {
19+
continue;
20+
}
21+
if (vis[nx][ny]) {
22+
return true;
23+
}
24+
q.offer(new int[] {nx, ny, x, y});
25+
vis[nx][ny] = true;
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}
32+
return false;
33+
}
34+
}

solution/1500-1599/1559.Detect Cycles in 2D Grid/Solution.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,28 @@
33
* @return {boolean}
44
*/
55
var containsCycle = function (grid) {
6-
const m = grid.length;
7-
const n = grid[0].length;
8-
let p = Array.from({ length: m * n }, (_, i) => i);
9-
function find(x) {
10-
if (p[x] != x) {
11-
p[x] = find(p[x]);
12-
}
13-
return p[x];
14-
}
15-
const dirs = [0, 1, 0];
16-
for (let i = 0; i < m; ++i) {
17-
for (let j = 0; j < n; ++j) {
18-
for (let k = 0; k < 2; ++k) {
19-
const x = i + dirs[k];
20-
const y = j + dirs[k + 1];
21-
if (x < m && y < n && grid[x][y] == grid[i][j]) {
22-
if (find(x * n + y) == find(i * n + j)) {
23-
return true;
6+
const [m, n] = [grid.length, grid[0].length];
7+
const vis = Array.from({ length: m }, () => Array(n).fill(false));
8+
const dirs = [-1, 0, 1, 0, -1];
9+
for (let i = 0; i < m; i++) {
10+
for (let j = 0; j < n; j++) {
11+
if (!vis[i][j]) {
12+
const q = [[i, j, -1, -1]];
13+
vis[i][j] = true;
14+
for (const [x, y, px, py] of q) {
15+
for (let k = 0; k < 4; k++) {
16+
const [nx, ny] = [x + dirs[k], y + dirs[k + 1]];
17+
if (nx >= 0 && nx < m && ny >= 0 && ny < n) {
18+
if (grid[nx][ny] !== grid[x][y] || (nx === px && ny === py)) {
19+
continue;
20+
}
21+
if (vis[nx][ny]) {
22+
return true;
23+
}
24+
q.push([nx, ny, x, y]);
25+
vis[nx][ny] = true;
26+
}
2427
}
25-
p[find(x * n + y)] = find(i * n + j);
2628
}
2729
}
2830
}
Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
class Solution:
2-
def containsCycle(self, grid: List[List[str]]) -> bool:
3-
def find(x):
4-
if p[x] != x:
5-
p[x] = find(p[x])
6-
return p[x]
7-
8-
m, n = len(grid), len(grid[0])
9-
p = list(range(m * n))
10-
for i in range(m):
11-
for j in range(n):
12-
for a, b in [[0, 1], [1, 0]]:
13-
x, y = i + a, j + b
14-
if x < m and y < n and grid[x][y] == grid[i][j]:
15-
if find(x * n + y) == find(i * n + j):
16-
return True
17-
p[find(x * n + y)] = find(i * n + j)
18-
return False
1+
class Solution:
2+
def containsCycle(self, grid: List[List[str]]) -> bool:
3+
m, n = len(grid), len(grid[0])
4+
vis = [[False] * n for _ in range(m)]
5+
dirs = (-1, 0, 1, 0, -1)
6+
for i, row in enumerate(grid):
7+
for j, x in enumerate(row):
8+
if vis[i][j]:
9+
continue
10+
vis[i][j] = True
11+
q = [(i, j, -1, -1)]
12+
while q:
13+
x, y, px, py = q.pop()
14+
for dx, dy in pairwise(dirs):
15+
nx, ny = x + dx, y + dy
16+
if 0 <= nx < m and 0 <= ny < n:
17+
if grid[nx][ny] != grid[i][j] or (nx == px and ny == py):
18+
continue
19+
if vis[nx][ny]:
20+
return True
21+
vis[nx][ny] = True
22+
q.append((nx, ny, x, y))
23+
return False
Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,41 @@
1-
impl Solution {
2-
#[allow(dead_code)]
3-
pub fn contains_cycle(grid: Vec<Vec<char>>) -> bool {
4-
let n = grid.len();
5-
let m = grid[0].len();
6-
let mut d_set: Vec<usize> = vec![0; n * m];
7-
8-
// Initialize the disjoint set
9-
for i in 0..n * m {
10-
d_set[i] = i;
11-
}
12-
13-
// Traverse the grid
14-
for i in 0..n {
15-
for j in 0..m {
16-
if i + 1 < n && grid[i + 1][j] == grid[i][j] {
17-
// Check the below cell
18-
let p_curr = Self::find(i * m + j, &mut d_set);
19-
let p_below = Self::find((i + 1) * m + j, &mut d_set);
20-
if p_curr == p_below {
21-
return true;
22-
}
23-
// Otherwise, union the two cells
24-
Self::union(p_curr, p_below, &mut d_set);
25-
}
26-
// Same to the right cell
27-
if j + 1 < m && grid[i][j + 1] == grid[i][j] {
28-
let p_curr = Self::find(i * m + j, &mut d_set);
29-
let p_right = Self::find(i * m + (j + 1), &mut d_set);
30-
if p_curr == p_right {
31-
return true;
32-
}
33-
// Otherwise, union the two cells
34-
Self::union(p_curr, p_right, &mut d_set);
35-
}
36-
}
37-
}
38-
39-
false
40-
}
41-
42-
#[allow(dead_code)]
43-
fn find(x: usize, d_set: &mut Vec<usize>) -> usize {
44-
if d_set[x] != x {
45-
d_set[x] = Self::find(d_set[x], d_set);
46-
}
47-
d_set[x]
48-
}
49-
50-
#[allow(dead_code)]
51-
fn union(x: usize, y: usize, d_set: &mut Vec<usize>) {
52-
let p_x = Self::find(x, d_set);
53-
let p_y = Self::find(y, d_set);
54-
d_set[p_x] = p_y;
55-
}
56-
}
1+
impl Solution {
2+
pub fn contains_cycle(grid: Vec<Vec<char>>) -> bool {
3+
let m = grid.len();
4+
let n = grid[0].len();
5+
let mut vis = vec![vec![false; n]; m];
6+
let dirs = vec![-1, 0, 1, 0, -1];
7+
8+
for i in 0..m {
9+
for j in 0..n {
10+
if !vis[i][j] {
11+
let mut q = vec![(i as isize, j as isize, -1, -1)];
12+
vis[i][j] = true;
13+
14+
while !q.is_empty() {
15+
let (x, y, px, py) = q.pop().unwrap();
16+
17+
for k in 0..4 {
18+
let nx = x + dirs[k];
19+
let ny = y + dirs[k + 1];
20+
if nx >= 0 && nx < m as isize && ny >= 0 && ny < n as isize {
21+
let nx = nx as usize;
22+
let ny = ny as usize;
23+
if grid[nx][ny] != grid[x as usize][y as usize]
24+
|| (nx == px as usize && ny == py as usize)
25+
{
26+
continue;
27+
}
28+
if vis[nx][ny] {
29+
return true;
30+
}
31+
q.push((nx as isize, ny as isize, x, y));
32+
vis[nx][ny] = true;
33+
}
34+
}
35+
}
36+
}
37+
}
38+
}
39+
false
40+
}
41+
}

0 commit comments

Comments
 (0)