距离顺序排列矩阵单元格


距离顺序排列矩阵单元格

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
给定四个整数 rows ,   cols ,  rCenter 和 cCenter 。有一个 rows x cols 的矩阵,你在单元格上的坐标是 (rCenter, cCenter) 。
返回矩阵中的所有单元格的坐标,并按与 (rCenter, cCenter) 的 距离 从最小到最大的顺序排。你可以按 任何 满足此条件的顺序返回答案。
单元格(r1, c1) 和 (r2, c2) 之间的距离为|r1 - r2| + |c1 - c2|。

示例 1:
输入:rows = 1, cols = 2, rCenter = 0, cCenter = 0
输出:[[0,0],[0,1]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1]

示例 2:
输入:rows = 2, cols = 2, rCenter = 0, cCenter = 1
输出:[[0,1],[0,0],[1,1],[1,0]]
解释:从 (r0, c0) 到其他单元格的距离为:[0,1,1,2]
[[0,1],[1,1],[0,0],[1,0]] 也会被视作正确答案。

示例 3:
输入:rows = 2, cols = 3, rCenter = 1, cCenter = 2
输出:[[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
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
思路:
根据距离中心点的距离一周一周的往外扩张

代码:
/**
* allCellsDistOrder
*
* @param $rows
* @param $cols
* @param $rCenter
* @param $cCenter
*
* @return array
*/
public function allCellsDistOrder($rows, $cols, $rCenter, $cCenter)
{
$dr = [1, 1, -1, -1];
$dc = [1, -1, -1, 1];

// 计算最大的曼哈顿距离,作为循环次数,纵向最远+横向最远
$maxDist = max($rCenter, $rows - 1 - $rCenter) + max($cCenter, $cols - 1 - $cCenter);
$ret = [];
$row = $rCenter;
$col = $cCenter;

// 先记录中心坐标
$ret[] = [$row, $col];

for ($dist = 0; $dist < $maxDist; $dist++) {
//坐标往左移动一格
$row--;

for ($i = 0; $i < 4; $i++) {
while (
// 循环直到有一个下标等于中心下标
(($i % 2 == 0) && $row != $rCenter) ||
(($i % 2 != 0) && $col != $cCenter)
) {
if ($row >= 0 && $row < $rows && $col >= 0 && $col < $cols) {
// 防止范围溢出
$ret[] = [$row, $col];
}
// 坐标运动 i=0往右上 1右下 2左下 3左上 ,坐菱形运动
$row += $dr[$i];
$col += $dc[$i];
}
}
}

return $ret;
}

流程图