LeetCode 1030 距离顺序排列矩阵单元格
https://leetcode-cn.com/problems/matrix-cells-in-distance-order/
法一 排序
以示例2为例,如下图所示,我们可以把[0, R)[0, C)
范围的所有6个点先保存起来,然后将它们按照和点(r0, c0)
(红色)的曼哈顿距离从近到远排序,返回排序后的结果即可。
class Solution {
public:
vector<vector<int>> allCellsDistOrder(int R, int C, int r0, int c0) {
vector<vector<int>> ans;
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
ans.push_back({i, j});
}
}
// [=]表示按值捕获可见范围内的所有局部变量
sort(ans.begin(), ans.end(), [=](vector<int>& a, vector<int>& b){
return abs(a[0] - r0) + abs(a[1] - c0) < abs(b[0] - r0) + abs(b[1] - c0);
});
return ans;
}
};
法二 BFS
因为题目要求按照距离给定点(r0, c0)
的曼哈顿距离从近到远的顺序返回所有的点,所以我们可以从给定点(r0, c0)
开始对整个矩阵中的点进行宽度优先搜索。如下图所示,对于每个点,我们从上下左右四个方向不断扩展其周围的点,并且使用数组标记某个点是否被访问过。我们只扩展在矩阵范围内并且还没有被访问过的点,这样的扩展能够确保矩阵中的点是按照要求的顺序访问的。
class Solution {
public:
vector<vector<int>> allCellsDistOrder(int R, int C, int r0, int c0) {
vector<vector<int>> ans;
// 上下左右四个扩展方向
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
vector<vector<bool>> vis(R, vector<bool>(C, false));
queue<pair<int, int>> q;
q.push(make_pair(r0, c0));
vis[r0][c0] = true;
while (!q.empty()) {
int sz = q.size();
for (int i = 0; i < sz; ++i) {
// 将当前点加入结果向量中
pair<int, int> curr = q.front();
q.pop();
ans.push_back({curr.first, curr.second});
// 扩展当前节点的周围节点
for (int x = 0; x < 4; ++x) {
int newi = curr.first + dx[x];
int newj = curr.second + dy[x];
if (0 <= newi && newi < R && 0 <= newj && newj < C && !vis[newi][newj]) {
q.push(make_pair(newi, newj));
vis[newi][newj] = true;
}
}
}
}
return ans;
}
};