You are given a 0-indexed m x n
binary matrix land
where a 0
represents a hectare of forested land and a 1
represents a hectare of farmland.
To keep the land organized, there are designated rectangular areas of hectares that consist entirely of farmland. These rectangular areas are called groups. No two groups are adjacent, meaning farmland in one group is not four-directionally adjacent to another farmland in a different group.
land
can be represented by a coordinate system where the top left corner of land
is (0, 0)
and the bottom right corner of land
is (m-1, n-1)
. Find the coordinates of the top left and bottom right corner of each group of farmland. A group of farmland with a top left corner at (r1, c1)
and a bottom right corner at (r2, c2)
is represented by the 4-length array [r1, c1, r2, c2].
Return a 2D array containing the 4-length arrays described above for each group of farmland in land
. If there are no groups of farmland, return an empty array. You may return the answer in any order.
Example 1:
Input: land = [[1,0,0],[0,1,1],[0,1,1]] Output: [[0,0,0,0],[1,1,2,2]] Explanation: The first group has a top left corner at land[0][0] and a bottom right corner at land[0][0]. The second group has a top left corner at land[1][1] and a bottom right corner at land[2][2].
Example 2:
Input: land = [[1,1],[1,1]] Output: [[0,0,1,1]] Explanation: The first group has a top left corner at land[0][0] and a bottom right corner at land[1][1].
Example 3:
Input: land = [[0]] Output: [] Explanation: There are no groups of farmland.
Constraints:
m == land.length
n == land[i].length
1 <= m, n <= 300
land
consists of only 0
's and 1
's.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding farmland groups means we'll look at every single possible area within the entire farm. We check each potential area to see if it matches the definition of a 'farmland group'. After checking every possible area we return those that are a farmland group.
Here's how the algorithm would work step-by-step:
def find_farmland_brute_force(land): rows = len(land)
cols = len(land[0]) if rows > 0 else 0
farmland_groups = []
for start_row in range(rows): for start_col in range(cols): for end_row in range(start_row, rows): for end_col in range(start_col, cols): is_farmland_group = True
# Check if all cells in the rectangle are farmland for row_check in range(start_row, end_row + 1): for col_check in range(start_col, end_col + 1): if land[row_check][col_check] != 1: is_farmland_group = False
break
if not is_farmland_group: break
if is_farmland_group: #Confirm the rectangle is the bottom-right most group is_bottom_right = True
if end_row + 1 < rows: for check_col in range(start_col, end_col + 1): if land[end_row + 1][check_col] == 1: is_bottom_right = False
break
if end_col + 1 < cols and is_bottom_right: for check_row in range(start_row, end_row + 1): if land[check_row][end_col + 1] == 1: is_bottom_right = False
break
#Only save results if bottom right rectangle if is_bottom_right: farmland_groups.append([start_row, start_col, end_row, end_col])
return farmland_groups
We need to identify rectangular groups of farmland within a grid. The trick is to efficiently explore the grid, marking farmland as we find it to avoid revisiting the same area. We can achieve this by searching from the top-left corner, and growing rectangles as we discover connected farmland.
Here's how the algorithm would work step-by-step:
def find_farmland(land_grid):
rows = len(land_grid)
cols = len(land_grid[0])
farmland_groups = []
for row_index in range(rows):
for col_index in range(cols):
if land_grid[row_index][col_index] == 1:
# Found farmland, explore to find its boundaries.
bottom_right_row = row_index
bottom_right_col = col_index
# Find the bottom right corner of the farmland rectangle.
while bottom_right_row + 1 < rows and land_grid[bottom_right_row + 1][col_index] == 1:
bottom_right_row += 1
while bottom_right_col + 1 < cols and land_grid[row_index][bottom_right_col + 1] == 1:
bottom_right_col += 1
farmland_groups.append([row_index, col_index, bottom_right_row, bottom_right_col])
# Mark the explored farmland as visited by changing its value.
for i in range(row_index, bottom_right_row + 1):
for j in range(col_index, bottom_right_col + 1):
land_grid[i][j] = 0
return farmland_groups
Case | How to Handle |
---|---|
Empty farmland array | Return an empty list since there's no farmland to group. |
Single cell farmland array (1x1) | Return a list containing a single group with top-left and bottom-right coordinates being (0, 0). |
All cells are farmland (all 1s) | Return a single group with top-left (0,0) and bottom-right (m-1, n-1) where m and n are dimensions. |
No farmland cells (all 0s) | Return an empty list since there is no farmland. |
Farmland forms multiple non-contiguous rectangles | The solution correctly identifies and returns each rectangle as a separate group using a traversal algorithm like DFS or BFS. |
Farmland array is not rectangular (invalid input) | Throw an IllegalArgumentException if the input array is not rectangular. |
Large farmland array (performance considerations) | Use iterative DFS or BFS instead of recursive approaches to avoid stack overflow errors and ensure reasonable time complexity. |
Farmland contains only one large rectangle. | Correctly identify the top-left and bottom-right coordinates of the single large rectangle. |