01矩阵

给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。 两个相邻元素间的距离为 1 。

在一个矩阵里只有0和1两种数字,求出每一个元素到最近一个0的距离,如果元素本身为0,则距离为0,在找最近0的过程只有四个方向,上下左右
从题目描述来看,不难得出我们在求某个元素的最近一个0的距离时,可以根据旁边的元素得到,因此我们可以使用动态规划
同时对于每一个元素1,我们可以从这个元素的上下左右去寻找一个最近的0,类似于广度优先遍历,因此我们也可以考虑用BFS的思想去完成

1. 动态规划

public int[][] updateMatrix(int[][] matrix) {
    // 动态规划
    int col = matrix[0].length;
    int row = matrix.length;
    int[][] dist = new int[row][col];
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (matrix[i][j] != 0) {
                // 如果矩阵的值不为0,则设置一个较大的值
                dist[i][j] = Integer.MAX_VALUE / 2;
            }
        }
    }
    // 左上
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (i > 0) {
            	// 上方元素
                dist[i][j] = Math.min(dist[i][j], 1 + dist[i - 1][j]);
            }
            if (j > 0) {
            	// 左方元素
                dist[i][j] = Math.min(dist[i][j], 1 + dist[i][j - 1]);
            }
        }
    }
    // 右下,注意遍历的顺序
    for (int i = row - 1; i >= 0; i--) {
        for (int j = col - 1; j >= 0; j--) {
            if (i < row - 1) {
            	// 当不是最后一行时,得到自己与(下方元素值+1)的较小值
                dist[i][j] = Math.min(dist[i][j], 1 + dist[i + 1][j]);
            }
            if (j < col - 1) {
            	// 右方元素
                dist[i][j] = Math.min(dist[i][j], 1 + dist[i][j + 1]);
            }
        }
    }
    return dist;
}

2. BFS

// 代表上下左右四个方向
static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

public int[][] updateMatrix(int[][] matrix) {
    // BFS
    int col = matrix[0].length;
    int row = matrix.length;
    // 每个队列的元素保存的是一个坐标
    Queue<int[]> queue = new LinkedList<>();
    // 保存矩阵中的每个元素是否被访问
    int isVisited[][] = new int[row][col];
    int dist[][] = new int[row][col];
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (matrix[i][j] == 0) {
                queue.offer(new int[]{i, j});
                isVisited[i][j] = 1;
            }
        }
    }
    while (!queue.isEmpty()) {
        int[] ele = queue.poll();
        int i = ele[0];
        int j = ele[1];
        // 对于元素的上下左右四个元素进行相应处理
        for (int k = 0; k < 4; k++) {
            int ii = i + dirs[k][0];
            int jj = j + dirs[k][1];
            if (ii > 0 && jj > 0 && ii < row && jj < col && isVisited[ii][jj] == 0) {
                dist[ii][jj] = dist[i][j] + 1;
                queue.offer(new int[]{ii, jj});
                isVisited[ii][jj] = 1;
            }
        }
    }
    return dist;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值