返回
JavaScript如何掌握LeetCode 1029.距离顺序排列矩阵单元格
前端
2023-11-03 23:53:40
## 前言
欢迎来到LeetCode系列文章的新一篇章,今天我们将一起探索「1029. 距离顺序排列矩阵单元格」这道题。这道题不仅考验算法设计能力,更需要我们对数据结构和优化技巧的娴熟掌握。通过本文,我们将从头到尾带你领略JavaScript解决该题的风采,并逐步掌握BFS与哈希法的妙用。
## 题意
给你一个下标从 0 开始的二维整数数组 matrix ,其中 matrix[r][c] 是第 r 行和第 c 列的元素。
同时给你一个数组 r0 和 c0 ,其中 r0 是 matrix 的行下标,c0 是 matrix 的列下标。
返回 matrix 的所有元素按照与 (r0, c0) 的距离升序排列后的结果。
换言之,按与 (r0, c0) 的 曼哈顿距离 从最小的到最大的顺序返回 matrix 的所有元素。
**示例 1:**
输入:matrix = [[1,0,1],[0,1,0],[1,0,1]], r0 = 1, c0 = 1
输出:[[0,1,0],[1,0,1],[1,0,1]]
解释:
- (1, 1) 到 (1, 1) 的距离为 0。
- (0, 0) 到 (1, 1) 的距离为 1。
- (2, 0) 到 (1, 1) 的距离为 1。
- (2, 2) 到 (1, 1) 的距离为 2。
- (0, 2) 到 (1, 1) 的距离为 2。
按距离从小到大排列后得到 [[0,1,0],[1,0,1],[1,0,1]]。
**示例 2:**
输入:matrix = [[1,0,0],[0,0,0],[0,0,0]], r0 = 1, c0 = 2
输出:[[1,0,0],[0,0,0],[0,0,0]]
解释:
- (1, 2) 到 (1, 2) 的距离为 0。
- (0, 0) 到 (1, 2) 的距离为 2。
- (0, 1) 到 (1, 2) 的距离为 2。
- (0, 2) 到 (1, 2) 的距离为 2。
- (2, 0) 到 (1, 2) 的距离为 2。
- (2, 1) 到 (1, 2) 的距离为 2。
- (2, 2) 到 (1, 2) 的距离为 2。
按距离从小到大排列后得到 [[1,0,0],[0,0,0],[0,0,0]]。
## 解法1:BFS+哈希
### 分析
距离顺序排列矩阵单元格,其实质就是找到矩阵中每个元素与给定单元格的曼哈顿距离,并根据距离进行排序。为此,我们可以采用广度优先搜索(BFS)和哈希表联手出击,先求出每个单元格到给定单元格的距离,再利用哈希表记录距离与单元格的对应关系,最后按照距离从小到大对单元格进行排序。
1. **BFS求距离:**
首先,我们利用BFS算法求出矩阵中每个单元格到给定单元格的曼哈顿距离。BFS的流程如下:
- 将给定单元格(r0, c0)加入队列。
- 循环执行以下操作,直到队列为空:
- 从队列中取出当前单元格。
- 将当前单元格的上下左右四个相邻单元格加入队列(注意越界)。
- 记录当前单元格到给定单元格的距离。
2. **哈希表存距离:**
接下来,我们使用哈希表来记录距离与单元格的对应关系。具体做法是:
- 对于矩阵中的每个单元格,计算其到给定单元格的距离。
- 将距离作为哈希表的键,单元格本身作为哈希表的值。
3. **排序输出结果:**
最后,我们将哈希表中的键值对按照距离从小到大进行排序,并将排序后的单元格输出。
### 代码实现
```javascript
/**
* 1029. 距离顺序排列矩阵单元格
* 给你一个下标从 0 开始的二维整数数组 matrix,其中 matrix[r][c] 是第 r 行和第 c 列的元素。
* 同时给你一个数组 r0 和 c0,其中 r0 是 matrix 的行下标,c0 是 matrix 的列下标。
* 返回 matrix 的所有元素按照与 (r0, c0) 的距离升序排列后的结果。
* 换言之,按与 (r0, c0) 的 曼哈顿距离 从最小的到最大的顺序返回 matrix 的所有元素。
* 示例 1:
* 输入:matrix = [[1,0,1],[0,1,0],[1,0,1]], r0 = 1, c0 = 1
* 输出:[[0,1,0],[1,0,1],[1,0,1]]
* 示例 2:
* 输入:matrix = [[1,0,0],[0,0,0],[0,0,0]], r0 = 1, c0 = 2
* 输出:[[1,0,0],[0,0,0],[0,0,0]]
* 提示:
* m == matrix.length
* n == matrix[r].length
* 1 <= m, n <= 100
* 0 <= r0 < m
* 0 <= c0 < n
* 1 <= matrix[r][c] <= 100
*/
const allCellsDistOrder = (matrix, r0, c0) => {
// BFS求距离
const distance = bfs(matrix, r0, c0);
// 哈希表存距离
const hash = {};
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
hash[distance[i][j]] = hash[distance[i][j]] || [];
hash[distance[i][j]].push([i, j]);
}
}
// 排序输出结果
const result = [];
for (const key in hash) {
result.push(...hash[key]);
}
return result;
};
// BFS求距离
const bfs = (matrix, r0, c0) => {
const m = matrix.length;
const n = matrix[0].length;
const distance = Array.from({ length: m }, () => Array(n).fill(0));
const queue = [[r0, c0]];
while (queue.length) {
const [r, c] = queue.shift();
if (r < 0 || r >= m || c < 0 || c >= n || matrix[r][c] === 0) {
continue;
}
distance[r][c] = distance[r0][c0] + 1;
matrix[r][c] = 0; // 标记已访问
queue.push([r - 1, c], [r + 1, c], [r, c - 1], [r, c + 1]);
}
return distance;
};
复杂度分析
- 时间复杂度: BFS的时间复杂度为O(mn),哈希表的插入和查找都是O(1),因此总的时间复杂度为O(mn)。
- 空间复杂度: BFS的空间复杂度为O(mn),哈希表的空间复杂度为O(mn),因此总的空间复杂度为O(mn)。
结语
通过本文,我们一起深入剖析了LeetCode 1029题的解法,并一步步实现了解决方案。从BFS的巧妙运用到哈希表的灵活搭配,希望你对算法设计