542. 01 Matrix

输入:元素值为0或者1的矩阵。
输出: 每个元素距离0的最近距离是多少。
规则:相邻单元格的距离是1,相邻是指上下左右4个方向。
分析:这类似于学习课程安排,可以从元素值为0的单元开始沿4个方向遍历。matrix[i][j]=0,那么距离result[i][j]=0,而且相邻元素的距离result[x][y]=result[i][j]+1。这样x,y也可以加入队列,继续遍历。对于已经计算好距离的元素需要标记好,防止重复计算。
进一步补充;这是一个从多个起点开始,求最短路径的问题。我们可以假设有一个超级零节点。这个节点到任意0节点的路径权重为0。这个超级零节点就是超级源点,这样就把问题转换为求从一个源点开始求最短路径问题。参考链接

在这里插入图片描述

private int[][] pos = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    public int[][] updateMatrix(int[][] matrix) {
        if(matrix==null || matrix.length==0) return null;
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] result = new int[m][n];
        for(int i=0;i<m;i++){
            Arrays.fill(result[i],-1);
        }
        Queue<int[]> queue = new LinkedList<int[]>();

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0){
                    result[i][j] = 0;
                    queue.offer(new int[]{i,j});
                }
            }
        }
        while(!queue.isEmpty()){
            int size = queue.size();
            for(int i=0;i<size;i++){
                int[] dot = queue.poll();
                for(List<Integer> newPosition : newPosition(dot[0],dot[1],m,n)){
                    int newx = newPosition.get(0);
                    int newy = newPosition.get(1);
                    if(result[newx][newy]==-1 || result[newx][newy] < result[dot[0]][dot[1]]+1){
                        result[newx][newy] = result[dot[0]][dot[1]]+1;
                        queue.offer(new int[]{newx,newy});
                    }
                }
            }
        }


        return result;
    }

    private List<List<Integer>> newPosition(int x,int y,int m,int n){
        List<List<Integer>> positionList = new ArrayList<List<Integer>>();
        for(int i=0;i<pos.length;i++){
            int newx = x+pos[i][0];
            int newy = y+pos[i][1];
            if(newx>=0 && newx<m && newy>=0 && newy<n){
                positionList.add(Arrays.asList(newx,newy));
            }
        }
        return positionList;
    }

分析2:DP思路。如果matrix[i][j]=0,则距离为0。如果matrix[i][j]=1,并且已经知道i,j周围所有元素的最短距离,那么 result[i][j]=min(result[i][j],min(各个方向的距离)+1)。各个方向是指上下左右。
 第一次遍历从左到右,从上到下,这样对于i,j来讲,左上的距离是确定的。
 第二次遍历从右到左,从下到上,这样对于i,j来讲,右下的距离是确定的。
 需要注意的是:result[i][j]的初始化值。如果matrix[0][0]=1,那么第一次遍历的时候,当处理到0,1元素的时候,result[0][0]=Integer.MAX_VALUE,执行Math.min(result[i][j],result[i][j-1]+1)会有Integer.MAX_VALUE+1这样一个溢出操作,所以result[i][j]的初始化值应该是Integer.MAX_VALUE-10000。减去的数值是随意写的。

 public int[][] updateMatrixDP(int[][] matrix) {
        if(matrix==null || matrix.length==0) return null;
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] result = new int[m][n];
        for(int i=0;i<m;i++){
            Arrays.fill(result[i],Integer.MAX_VALUE-10000);
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(matrix[i][j]==0){
                    result[i][j]=0;
                }else{
                    if(i>0){
                        result[i][j]=Math.min(result[i][j],result[i-1][j]+1);
                    }
                    if(j>0){
                        result[i][j]=Math.min(result[i][j],result[i][j-1]+1);
                    }
                }
            }
        }

        for(int i=m-1;i>=0;i--){
            for (int j=n-1;j>=0;j--){
                if(i<m-1){
                    result[i][j]=Math.min(result[i][j],result[i+1][j]+1);
                }
                if(j<n-1){
                    result[i][j]=Math.min(result[i][j],result[i][j+1]+1);
                }
            }
        }

        return result;
    }

代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值