kylin来刷题啦-Day10:1030. 距离顺序排列矩阵单元格

157 阅读1分钟

这是我参与更文挑战的第21天,活动详情查看: 更文挑战

1030. 距离顺序排列矩阵单元格

题目描述

给出 R 行 C 列的矩阵,其中的单元格的整数坐标为 (r, c),满足 0 <= r < R 且 0 <= c < C。

另外,我们在该矩阵中给出了一个坐标为 (r0, c0) 的单元格。

返回矩阵中的所有单元格的坐标,并按到 (r0, c0) 的距离从最小到最大的顺序排,其中,两单元格(r1, c1) 和 (r2, c2) 之间的距离是曼哈顿距离,|r1 - r2| + |c1 - c2|。(你可以按任何满足此条件的顺序返回答案。)

示例 1 :

输入:R = 1, C = 2, r0 = 0, c0 = 0

输入:R = 1, C = 2, r0 = 0, c0 = 0

输出:[[0,0],[0,1]]

解释:从 (r0, c0) 到其他单元格的距离为:[0,1]

示例 2 :

输入:R = 2, C = 2, r0 = 0, c0 = 1

输出:[[0,1],[0,0],[1,1],[1,0]]

解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2]

[[0,1],[1,1],[0,0],[1,0]] 也会被视作正确答案。

示例 3:

输出:[[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]]

解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2,2,3]

其他满足题目要求的答案也会被视为正确,例如 [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]。

提示:

  1. 1 <= R <= 100
  2. 1 <= C <= 100
  3. 0 <= r0 < R
  4. 0 <= c0 < C

友情链接

leetcode-cn.com/problems/ma…

思路解析

此题我们用桶排序算法来解。

  1. 初始化桶。先根据曼哈顿距离来确定需要多少个桶。桶的个数也就是矩阵中曼哈顿距离的最大值。
  2. 从矩阵的原点开始依次遍历各坐标,算出该点坐标与给定坐标点的曼哈顿距离。并将该点坐标放入对应的桶里。
  3. 根据桶的结构,所有坐标点已经排好序。封装成返回参数的格式进行输出。

算法实现

class Solution {
    public int[][] allCellsDistOrder(int rows, int cols, int rCenter, int cCenter) {
        int maxDist = Math.max(rCenter, rows-1-rCenter)+Math.max(cCenter,cols-1-cCenter);
        List<List<int[]>> bucket=new ArrayList<List<int[]>>();
        for(int i=0;i<=maxDist;i++){
            bucket.add(i,new ArrayList<int[]>());
        }
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                int dist=dist(i,j,rCenter,cCenter);
                bucket.get(dist).add(new int[]{i,j});
            }
        }

        int ret[][]=new int[rows*cols][];
        int index=0;
        for(int i=0;i<=maxDist;i++){
            for(int[] bt:bucket.get(i)){
                ret[index++]=bt;
            }
        }
        return ret;
    }

    public int dist(int r1,int r2,int c1,int c2){
        return Math.abs(r1-c1)+Math.abs(r2-c2);
    }
}

运行结果

image.png

另类写法

另外这种解法巧妙利用了 TreeMap 的数据结构,但是效率不是很好。比较看看就行。

class Solution {
    public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
        var distMap = new TreeMap<Integer,List<int[]>>();
        
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                int dist = Math.abs(r0 - i) + Math.abs(c0 - j);
                distMap.computeIfAbsent(dist, k -> new ArrayList<int[]>()).add(new int[] {i,j});
            }
        }
        return distMap.values().stream().flatMap(List::stream).toArray(int[][]::new);
    }
}

image.png