Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Leetcode 1162. As Far from Land as Possible

Woodyiiiiiii opened this issue · comments

这道题我一开始想着也是直接用DP来做,但显然,递进方程的推导跟增加顺序有关,单单从左上到右下这一顺序是不够的,所以要包括从右下到左上这一个顺序。

class Solution {
    public int maxDistance(int[][] grid) {
        int ans = 0;
        int n = grid.length;
        int[][] dist = new int[n][n];
        for (int i = 0; i < n; ++i) {
            Arrays.fill(dist[i], Integer.MAX_VALUE);
        }
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    dist[i][j] = 0;
                } else {
                    if (i - 1 >= 0 && dist[i - 1][j] != Integer.MAX_VALUE) {
                        dist[i][j] = Math.min(dist[i][j], dist[i - 1][j] + 1);
                    }
                    if (j - 1 >= 0 && dist[i][j - 1] != Integer.MAX_VALUE) {
                        dist[i][j] = Math.min(dist[i][j], dist[i][j - 1] + 1);
                    }
                }
            }
        }
        for (int i = n - 1; i >= 0; --i) {
            for (int j = n - 1; j >= 0; --j) {
                if (grid[i][j] == 1) {
                    dist[i][j] = 0;
                } else {
                    if (i + 1 < n && dist[i + 1][j] != Integer.MAX_VALUE) {
                        dist[i][j] = Math.min(dist[i][j], dist[i + 1][j] + 1);
                    }
                    if (j + 1 < n && dist[i][j + 1] != Integer.MAX_VALUE) {
                        dist[i][j] = Math.min(dist[i][j], dist[i][j + 1] + 1);
                    }
                }
                ans = Math.max(ans, dist[i][j]);
            }
        }
        return ans == 0 || ans == Integer.MAX_VALUE ? -1 : ans;
    }
}

第二种方法是BFS

我们从节点为1的位置出发,每次BFS扩散一轮,结果加一,然后要将经历过的节点置1(路径覆盖),这样最后一轮就是最远的0节点的位置。

class Solution {
    final int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

    public int maxDistance(int[][] grid) {
        int ans = 0;
        int n = grid.length;
        Queue<int[]> q = new LinkedList<>();
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == 1) {
                    q.offer(new int[]{i, j});
                }
            }
        }
        while (!q.isEmpty()) {
            int sz = q.size();
            while (sz-- > 0) {
                int[] cur = q.poll();
                for (int[] dir : dirs) {
                    int x = cur[0] + dir[0];
                    int y = cur[1] + dir[1];
                    if (x < 0 || x >= n || y < 0 || y >= n || grid[x][y] == 1) continue;
                    grid[x][y] = 1;
                    q.offer(new int[]{x, y});
                }
            }
            ++ans;
        }
        return ans - 1 <= 0 ? -1 : ans - 1;
    }
}

我尝试过用DFS+记忆化搜索来做,但很难判断回环的情况。

BFS和DFS两种方法,时间复杂度都要尽量保持在O(mnlgmn)以下,同时也要解决的问题。

看下这题2328. Number of Increasing Paths in a Grid