You are given a 0-indexed 2D matrix grid
of size m x n
, where (r, c)
represents:
grid[r][c] = 0
, orgrid[r][c]
fish, if grid[r][c] > 0
.A fisher can start at any water cell (r, c)
and can do the following operations any number of times:
(r, c)
, orReturn the maximum number of fish the fisher can catch if he chooses his starting cell optimally, or 0
if no water cell exists.
An adjacent cell of the cell (r, c)
, is one of the cells (r, c + 1)
, (r, c - 1)
, (r + 1, c)
or (r - 1, c)
if it exists.
Example 1:
grid = [[0,2,1,0],[4,0,0,3],[1,0,0,4],[0,3,2,0]]
Output: 7
Explanation: The fisher can start at cell `(1,3)` and collect 3 fish, then move to cell `(2,3)` and collect 4 fish.
Example 2:
grid = [[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]
Output: 1
Explanation: The fisher can start at cells (0,0) or (3,3) and collect a single fish.
Can you provide an efficient algorithm to solve this problem, along with its time and space complexity analysis? Also, discuss any edge cases that need to be considered.
A brute-force approach would involve starting at each water cell (grid[r][c] > 0) and exploring all possible paths to adjacent water cells using a depth-first search (DFS) or breadth-first search (BFS). We would keep track of the maximum number of fish collected along any path and return that value.
A more efficient approach also uses DFS, but it marks visited cells to avoid cycles and redundant computations. For each water cell, we initiate a DFS to explore the connected component of water cells. During the DFS, we accumulate the number of fish in the connected component. We keep track of the maximum number of fish found across all connected components.
max_fish
to 0.(r, c)
in the grid.grid[r][c] > 0
, start a DFS from that cell:
grid[r][c] = 0
(or using a separate visited array).(r+1, c)
, (r-1, c)
, (r, c+1)
, (r, c-1)
. Add the fish in each adjacent cell to the current fish count.max_fish
with the maximum fish count found so far.max_fish
.def max_fish_catch(grid):
m, n = len(grid), len(grid[0])
def dfs(r, c):
if r < 0 or r >= m or c < 0 or c >= n or grid[r][c] == 0:
return 0
fish = grid[r][c]
grid[r][c] = 0 # Mark as visited
fish += dfs(r + 1, c)
fish += dfs(r - 1, c)
fish += dfs(r, c + 1)
fish += dfs(r, c - 1)
return fish
max_fish = 0
for r in range(m):
for c in range(n):
if grid[r][c] > 0:
max_fish = max(max_fish, dfs(r, c))
return max_fish
# Example usage:
grid = [[0, 2, 1, 0], [4, 0, 0, 3], [1, 0, 0, 4], [0, 3, 2, 0]]
print(max_fish_catch(grid)) # Output: 7
Consider the grid:
[[0, 2, 1, 0],
[4, 0, 0, 3],
[1, 0, 0, 4],
[0, 3, 2, 0]]
The algorithm will:
grid
values are set to 0 as the algorithm progresses and avoids revisiting the same grid.The maximum fish caught will be 7 (3+4).