困难-5482.-二维网格图中探测环

LeetCode 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;
    }
};
原文地址:https://www.cnblogs.com/faded828x/p/13547879.html