leetcode
leetcode 2951 ~ 3000
01 矩阵

01 矩阵

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 104 ms, 内存: 20.3 MB


/*
题目思路:
1. 创建一个结果矩阵result,用于存储每个位置到最近的0的距离。
2. 使用两个队列分别存储当前层和下一层的元素,初始时将所有的0的位置加入队列。
3. 对队列中的每个元素进行广度优先搜索(BFS),更新其邻居的距离,如果邻居的距离更新,加入下一层队列。
4. 循环进行BFS,直到队列为空。
*/
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.stream.IntStream;

public class Solution {
    public int[][] updateMatrix(int[][] mat) {
        int m = mat.length, n = mat[0].length;
        int[][] result = new int[m][n];
        boolean[][] visited = new boolean[m][n];
        Queue<int[]> queue = new LinkedList<>();

        IntStream.range(0, m).forEach(i -> IntStream.range(0, n).forEach(j -> {
            if (mat[i][j] == 0) {
                queue.offer(new int[]{i, j});
                visited[i][j] = true;
            }
        }));

        int[] directions = {-1, 0, 1, 0, -1};

        while (!queue.isEmpty()) {
            int[] cell = queue.poll();
            int x = cell[0], y = cell[1];
            for (int k = 0; k < 4; k++) {
                int newX = x + directions[k];
                int newY = y + directions[k + 1];
                if (newX >= 0 && newX < m && newY >= 0 && newY < n && !visited[newX][newY]) {
                    result[newX][newY] = result[x][y] + 1;
                    queue.offer(new int[]{newX, newY});
                    visited[newX][newY] = true;
                }
            }
        }

        return result;
    }
}

解释

方法:

本题解采用广度优先搜索(BFS)来找出矩阵中每个元素到最近的0的距离。首先,将所有值为0的元素的位置加入到队列中,并初始化它们的距离为0。对于矩阵中的1,距离初始化为-1表示未访问。队列中的元素依次出队,对其四个方向的邻居进行检查。如果邻居未被访问过(即距离为-1),则更新其距离为当前元素的距离加1,并将其加入队列中继续处理。这一过程重复进行,直到队列为空。

时间复杂度:

O(m*n)

空间复杂度:

O(m*n)

代码细节讲解

🦆
为什么在初始化距离矩阵时选择-1作为未访问的标识,而不是使用其他数值或者数据结构?
在初始化距离矩阵时选择-1作为未访问的标识是因为-1在此上下文中是一个明显的非法值,因为距离不可能为负数。使用-1可以立即区分出哪些元素尚未被访问或更新,这样做可以避免使用额外的数据结构来跟踪访问状态,从而节省内存和简化代码逻辑。如果使用其他数值,如正整数,可能会与有效的距离值混淆,使得算法的判断更加复杂。
🦆
在广度优先搜索中,如何保证每个点只被访问一次,避免重复计算?
在广度优先搜索(BFS)中,通过一个访问记录矩阵 'travel' 来确保每个点只被访问一次。一旦一个点被访问,即将它的访问状态标记为 'True'。在后续的搜索过程中,只有未被访问(即其状态为 'False')的点才会被加入到队列中。这样确保了每个点仅在首次达到时被处理一次,避免了重复计算和不必要的资源浪费。
🦆
算法中提到的队列是如何影响BFS的执行效率的?使用栈实现深度优先搜索(DFS)会有什么不同的效果?
在BFS中,使用队列是为了保证先进入队列的节点先被处理,从而按层次(从近到远)处理每个节点。这种层次化处理确保了距离的正确计算,并且能够较快地到达所有节点。而使用栈实现深度优先搜索(DFS)会导致算法先深入到可能的最远点,这样做在寻找最短路径问题中效率较低,因为它可能走很多不必要的路径。此外,DFS在处理大数据量时可能会因递归过深而导致栈溢出,而BFS则通常不会遇到这样的问题。

相关问题