题目链接:https://leetcode.cn/problems/find-all-groups-of-farmland/
题目大意:二维数组land[][]
中元素均为0
和1
,1
代表农场,0
代表森林。农场连成一块叫农场组,农场组只会以矩形的形式出现。求所有的农场组的左上角和右下角坐标。
思路:很容易想到BFS,每个组的首个和末个元素就是左上角和右下角坐标。
BFS代码
class Solution {
public:
vector<vector<int>> findFarmland(vector<vector<int>>& land) {
int M = land.size(), N = land[0].size();
vector<vector<bool>> known(M, vector<bool>(N, false));
vector<vector<int>> ret;
queue<vector<int>> q;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (!known[i][j]) {
known[i][j] = true;
q.push({i, j});
vector<vector<int>> group;
while (!q.empty()) {
int x = q.front()[0], y = q.front()[1];
if (land[x][y]) {
group.push_back({x, y});
if (x+1 < M) {
if (!known[x+1][y]) {
known[x+1][y] = true;
if (land[x+1][y])
q.push({x+1, y});
}
}
if (y+1 < N) {
if (!known[x][y+1]) {
known[x][y+1] = true;
if (land[x][y+1])
q.push({x, y+1});
}
}
}
q.pop();
}
if (group.size()) {
ret.push_back({group[0][0], group[0][1], group.back()[0], group.back()[1]});
}
}
}
}
return ret;
}
};
提交通过了但发现时间开销有点大,于是想了一想,既然农场组都是矩形,其实只要找到这个矩形的长宽就OK,也就是往右和往下找直到碰到森林为止。中间的一大部分农场实际上不需要访问。于是做了一下优化。果然时间开销小了很多。
完整代码
class Solution {
public:
vector<vector<int>> findFarmland(vector<vector<int>>& land) {
int M = land.size(), N = land[0].size();
vector<vector<bool>> known(M, vector<bool>(N, false));
vector<vector<int>> ret;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (!known[i][j]) {
known[i][j] = true;
if (land[i][j]) {
int x = i+1, y = j+1;
while (x < M && land[x][j])
x++;
x--;
while (y < N && land[i][y])
y++;
y--;
ret.push_back({i, j, x, y});
for (int i2 = i; i2 <= x; i2++) {
for (int j2 = j; j2 <= y; j2++)
known[i2][j2] = true;
}
}
}
}
}
return ret;
}
};