本文最后更新于:2023年3月19日 晚上
                
              
            
            
              Lt1030. 距离顺序排列矩阵单元格,桶排序,BFS
给出 R 行 C 列的矩阵,其中的单元格的整数坐标为 (r, c),满足 0 <= r < R 且 0 <= c < C。
另外,我们在该矩阵中给出了一个坐标为 (r0, c0) 的单元格。
返回矩阵中的所有单元格的坐标,并按到 (r0, c0) 的距离从最小到最大的顺序排,其中,两单元格(r1, c1) 和 (r2, c2) 之间的距离是曼哈顿距离,|r1 - r2| + |c1 - c2|。(你可以按任何满足此条件的顺序返回答案。)
 示例 1:
1 2 3
   | 输入:R = 1, C = 2, r0 = 0, c0 = 0 输出:[[0,0],[0,1]] 解释:从 (r0, c0) 到其他单元格的距离为:[0,1]
 
  | 
 
示例 2:
1 2 3 4
   | 输入:R = 2, C = 2, r0 = 0, c0 = 1 输出: 解释:从 (r0, c0) 到其他单元格的距离为:  也会被视作正确答案。
 
  | 
 
示例 3:
1 2 3 4
   | 输入:R = 2, C = 3, r0 = 1, c0 = 2 输出: 解释:从 (r0, c0) 到其他单元格的距离为: 其他满足题目要求的答案也会被视为正确,例如 。
 
  | 
 
提示:
1 <= R <= 100 
1 <= C <= 100 
0 <= r0 < R 
0 <= c0 < C 
思路
直接排序
先生成一个所有点数组,再根据曼哈顿距离升序排序即可。
桶排序
使用桶排序,节省了排序的步骤。根据距离在 map 中放置元素,再遍历 map,默认就是从最小到最大距离来遍历。直接将对应的 value 连接上结果数组中即可。
BFS
1 2 3 4 5
   | 5 4 3 2 3 4 5 4 3 2 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 2 3 4 5 4 3 2 3 4 5
 
  | 
 
BFS 思想,曼哈顿距离如以上矩阵所示。使用一个矩阵记录当前点是否已遍历过,将当前点加入结果数组,然后将当前点上下左右的点加入队列,并设为已访问过。加入结果数组的顺序根据 BFS 过程,一定符合曼哈顿距离从小到大的顺序。
解答
直接排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | 
 
 
 
 
 
  var allCellsDistOrder = function (R, C, r0, c0) {   const points = [];   points.push(new Array(R * C));   let index = 0;   for (let x = 0; x < R; x++) {     for (let y = 0; y < C; y++) {       points[index++] = [x, y];     }   }   points.sort(     (a, b) =>       Math.abs(r0 - a[0]) +       Math.abs(c0 - a[1]) -       (Math.abs(r0 - b[0]) + Math.abs(c0 - b[1]))   );   return points; };
 
  | 
 
桶排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | 
 
 
 
 
 
  var allCellsDistOrder = function (R, C, r0, c0) {   const getDistance = (point) =>     Math.abs(r0 - point[0]) + Math.abs(c0 - point[1]);   const map = {};   for (let x = 0; x < R; x++) {     for (let y = 0; y < C; y++) {       const distance = getDistance([x, y]);       if (map[distance]) map[distance].push([x, y]);       else map[distance] = [[x, y]];     }   }   return Object.values(map).reduce((a, b) => a.concat(b), []); };
 
  | 
 
BFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
   | 
 
 
 
 
 
  var allCellsDistOrder = function (R, C, r0, c0) {   const visited = Array.from(new Array(R)).map(() => new Array(C).fill(0));   const queue = [[r0, c0]];   visited[r0][c0] = 1;   const res = [];   while (queue.length) {     const point = queue.shift();     const x = point[0],       y = point[1];     res.push(point);     if (x - 1 >= 0 && !visited[x - 1][y]) {       queue.push([x - 1, y]);       visited[x - 1][y] = 1;     }     if (y - 1 >= 0 && !visited[x][y - 1]) {       queue.push([x, y - 1]);       visited[x][y - 1] = 1;     }     if (x + 1 < R && !visited[x + 1][y]) {       queue.push([x + 1, y]);       visited[x + 1][y] = 1;     }     if (y + 1 < C && !visited[x][y + 1]) {       queue.push([x, y + 1]);       visited[x][y + 1] = 1;     }   }   return res; };
 
  |