网格图中鱼的最大数目
难度:
标签:
题目描述
You are given a 0-indexed 2D matrix grid
of size m x n
, where (r, c)
represents:
- A land cell if
grid[r][c] = 0
, or - A water cell containing
grid[r][c]
fish, ifgrid[r][c] > 0
.
A fisher can start at any water cell (r, c)
and can do the following operations any number of times:
- Catch all the fish at cell
(r, c)
, or - Move to any adjacent water cell.
Return 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:

Input: 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:

Input: 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.
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 10
0 <= grid[i][j] <= 10
代码结果
运行时间: 65 ms, 内存: 16.3 MB
/*
* 思路:
* 1. 使用 Java Stream API 对网格进行流式操作。
* 2. 将所有水域格子的坐标及其鱼数转化为流的元素。
* 3. 对于每个水域格子,使用递归函数(在流中)计算从该格子出发能够捕捞的最多鱼数。
* 4. 使用 reduce 函数找到最大的鱼数。
*/
import java.util.stream.Stream;
public class MaxFishStream {
public int maxFish(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
return Stream.iterate(new int[]{0, 0}, pos -> pos[0] < m && pos[1] < n, pos -> new int[]{pos[0] + (pos[1] + 1) / n, (pos[1] + 1) % n})
.filter(pos -> grid[pos[0]][pos[1]] > 0)
.mapToInt(pos -> dfs(grid, new boolean[m][n], pos[0], pos[1]))
.max()
.orElse(0);
}
private int dfs(int[][] grid, boolean[][] visited, int r, int c) {
if (r < 0 || c < 0 || r >= grid.length || c >= grid[0].length || grid[r][c] == 0 || visited[r][c]) {
return 0;
}
visited[r][c] = true;
int fish = grid[r][c];
// 四个方向移动
fish += dfs(grid, visited, r + 1, c);
fish += dfs(grid, visited, r - 1, c);
fish += dfs(grid, visited, r, c + 1);
fish += dfs(grid, visited, r, c - 1);
return fish;
}
}
解释
方法:
此题目要求计算渔夫在最优策略下能捕获的最大鱼数。基本思路是采用深度优先搜索(DFS),遍历每一个水域单元格,并计算从该单元格出发能够访问到的所有相连水域单元格中的鱼的总数。针对每个水域,我们执行DFS,标记访问过的单元格为陆地(即设置为0),以避免重复访问。每次DFS都会更新一个全局变量来记录当前连通水域中的总鱼数,并与全局最大值进行比较更新。这样,遍历完整个网格后,全局最大值即为所求的最大鱼数。
时间复杂度:
O(m*n)
空间复杂度:
O(m*n)
代码细节讲解
🦆
在这个题解中,为什么选择使用深度优先搜索(DFS)而不是广度优先搜索(BFS)或其他图搜索算法?
▷🦆
题解中提到将已访问的水域单元格标记为0以避免重复访问,这种方法是否会影响原始数据结构,如果是,应该如何处理以便保留原始网格状态?
▷🦆
解题思路中提到每次DFS更新全局变量`p`来记录当前连通水域中的鱼的总数,这种使用全局变量的方法是否有可能导致线程安全问题或者在并行处理中出现问题?
▷🦆
DFS递归过程中,如果遇到极端情况,例如非常大的水域连通区域,递归深度过大可能会导致栈溢出,题解中有没有考虑这种情况,应如何优化?
▷