困难-5482.-二维网格图中探测环
该题是双周赛试题,所以编号可能搜不到。要开学了,忙着复习考试,高数花了三四天学完,虽然一个学期没听,不过寒假学的好,所以问题不大,稍微看看了级数和复变函数的题,应该问题不大。
现在在看电工电子,电路部分快结束了,模电一点都没学,不知道要啃多久。物理的话寒假学了部分,电磁学一点没看,力学和热学也基本忘光了。(补:结果两天就肝完了模电)
:) 不过还是抽时间花了一个半小时肝这次力扣赛,明天的周赛就水一水吧。这道题是我第一次解出力扣赛6分的困难题,继续加油。说实话我觉得这类迷宫型用dfs我都蛮擅长的。
给你一个二维字符网格数组 grid
,大小为 m x n
,你需要检查 grid
中是否存在 相同值 形成的环。
一个环是一条开始和结束于同一个格子的长度 大于等于 4 的路径。对于一个给定的格子,你可以移动到它上、下、左、右四个方向相邻的格子之一,可以移动的前提是这两个格子有 相同的值 。
同时,你也不能回到上一次移动时所在的格子。比方说,环 (1, 1) -> (1, 2) -> (1, 1)
是不合法的,因为从 (1, 2)
移动到 (1, 1)
回到了上一次移动时的格子。
如果 grid
中有相同值形成的环,请你返回 true
,否则返回 false
。
这是我debug四次整出来的,主要超时用fail数组解决。
class Solution { static int[][] move = new int[][] { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } }; public boolean containsCycle(char[][] grid) { int row = grid.length; int col = grid[0].length; boolean[][] visit = new boolean[row][col]; boolean[][] fail = new boolean[row][col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if(fail[i][j]) continue; if (dfs(grid, visit, i, j, -1, fail)) return true; } } return false; } public boolean dfs(char[][] grid, boolean[][] visit, int x, int y, int dire, boolean[][] fail) { int row = grid.length; int col = grid[0].length; if (visit[x][y]) return true; visit[x][y] = true; for (int i = 0; i < 4; i++) { if (dire != -1 && (i == dire + 2 || i == dire - 2)) continue; int curX = x + move[i][0]; int curY = y + move[i][1]; if (curX >= 0 && curX < row && curY >= 0 && curY < col && grid[curX][curY] == grid[x][y]) if (dfs(grid, visit, curX, curY, i, fail)) return true; } visit[x][y] = false; fail[x][y] = true; return false; } }
这是排名第一的大佬写的,说实话我完全不知道他写的什么玩意。orz
class UF { public: vector<int> fa; vector<int> sz; int n; int comp_cnt; public: UF(int _n): n(_n), comp_cnt(_n), fa(_n), sz(_n, 1) { iota(fa.begin(), fa.end(), 0); } int findset(int x) { return fa[x] == x ? x : fa[x] = findset(fa[x]); } void unite(int x, int y) { if (sz[x] < sz[y]) { swap(x, y); } fa[y] = x; sz[x] += sz[y]; --comp_cnt; } bool findAndUnite(int x, int y) { int x0 = findset(x); int y0 = findset(y); if (x0 != y0) { unite(x0, y0); return true; } return false; } }; class Solution { public: bool containsCycle(vector<vector<char>>& grid) { int m = grid.size(); int n = grid[0].size(); UF uf(m * n); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (i > 0 && grid[i][j] == grid[i - 1][j]) { if (!uf.findAndUnite(i * n + j, (i - 1) * n + j)) { return true; } } if (j > 0 && grid[i][j] == grid[i][j - 1]) { if (!uf.findAndUnite(i * n + j, i * n + j - 1)) { return true; } } } } return false; } };