目录
题目解析 | 1992. 找到所有的农场组 —— 矩形农场识别问题
题目解析 | 1992. 找到所有的农场组 —— 矩形农场识别问题
题目描述
给定一个大小为 m x n 的二维二进制矩阵 land,其中:
0表示一单位的森林土地,1表示一单位的农场土地。
题目保证所有的农场土地都是以 矩形 形式组成的农场组,且不同的农场组之间不会在上下左右方向相邻(不会相互接触)。换句话说:
- 每个农场组是一个完整的矩形区域,
- 不同农场组之间至少有一圈
0分隔。
你的任务是找到所有农场组的左上角和右下角坐标,返回一个二维数组,每个子数组是 [r1, c1, r2, c2],分别表示一个农场组的左上角和右下角坐标。
如果没有任何农场组,返回空数组。
输入输出示例
示例 1:
输入:
land = [
[1,0,0],
[0,1,1],
[0,1,1]
]
输出:
[[0,0,0,0],[1,1,2,2]]
解释:
- 第一个农场组只有一个1,位于 (0,0) 位置。
- 第二个农场组是一个2x2矩形,左上角在 (1,1),右下角在 (2,2)。
示例 2:
输入:
land = [
[1,1],
[1,1]
]
输出:
[[0,0,1,1]]
解释:
只有一个农场组,整个矩阵都是农场土地。
示例 3:
输入:
land = [
[0]
]
输出:
[]
解释:
没有任何农场组。
解题分析
题目重点在于:
- 农场组都是矩形
这让我们可以用边界扫描确定一个农场组的位置,而不必考虑复杂的形状和连通性。 - 不同农场组之间不相邻
这保证了每次遇到一个1,它一定是一个新的农场组的左上角,避免重叠计数。 - 需要返回矩形的左上角和右下角坐标
找到起点后,需要沿着矩形边界扩展宽度和高度。
解题思路与方法
1. 遍历矩阵
- 对矩阵进行双重循环遍历,
- 每遇到一个
1,即找到一个新农场组的左上角坐标(r1, c1)。
2. 寻找矩形右边界
- 从左上角
(r1, c1)向右扫描,确定矩形宽度(列范围c1到c2), - 直到遇到
0或边界停止。
3. 寻找矩形下边界
- 确定了宽度后,从左上角向下扫描行,
- 逐行检查该列范围内是否全是
1, - 如果整行对应列都是
1,继续向下扩展, - 否则停止,确定下边界行号
r2。
4. 标记矩形区域为已访问
- 将找到的矩形内所有
1改为0,防止后续重复计数。
5. 记录矩形坐标
- 将
[r1, c1, r2, c2]记录到结果列表中。
代码实现(Python)
from typing import List
class Solution:
def findFarmland(self, land: List[List[int]]) -> List[List[int]]:
m, n = len(land), len(land[0])
result = []
for i in range(m):
for j in range(n):
if land[i][j] == 1:
r1, c1 = i, j
r2, c2 = i, j
# 向右找宽度
while c2 + 1 < n and land[i][c2 + 1] == 1:
c2 += 1
# 向下找高度
temp_r = i
while temp_r + 1 < m:
# 检查下一行的对应列是否全为1
all_one = True
for col in range(c1, c2 + 1):
if land[temp_r + 1][col] != 1:
all_one = False
break
if all_one:
temp_r += 1
else:
break
r2 = temp_r
# 标记已访问区域
for x in range(r1, r2 + 1):
for y in range(c1, c2 + 1):
land[x][y] = 0
result.append([r1, c1, r2, c2])
return result
复杂度分析
- 时间复杂度:
遍历矩阵O(m*n),每个元素最多被访问两次(一次扫描,一次标记),整体是线性的。 - 空间复杂度:
使用原地修改land,空间复杂度为O(1)。
方案比较
- DFS/BFS方法:
也可以用深度优先或广度优先遍历农场组,但由于题目保证农场为矩形,这样做较为繁琐且效率稍低。 - 当前方法优点:
利用题目矩形性质直接按边界扫描,简单高效。
示例讲解
以示例1为例:
land = [
[1,0,0],
[0,1,1],
[0,1,1]
]
- 遍历到
land[0][0] == 1:
-
- 向右无延伸,宽度=1,
- 向下无延伸,高度=1,
- 标记
[0,0,0,0]为已访问。
- 继续遍历,到
land[1][1] == 1:
-
- 向右延伸到
land[1][2] == 1,宽度=2, - 向下延伸到
land[2][1], land[2][2] == 1,高度=2, - 标记区域
[1,1,2,2]为已访问。
- 向右延伸到
- 结果为
[[0,0,0,0],[1,1,2,2]]。
总结
- 利用题目中“农场为矩形且不相邻”的特点,大大简化了问题,
- 遍历时遇到
1直接定位矩形边界,标记后避免重复, - 该方法简单易实现,时间空间效率都很好。
270

被折叠的 条评论
为什么被折叠?



