你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n
的网格 grid
进行了标注。每一个单元格中的整数就表示这一单元格中的黄金数量;若是该单元格是空的,那么就是 0
。java
为了使收益最大化,矿工须要按如下规则来开采黄金:web
0
的单元格。输入:grid = [[0,6,0],[5,8,7],[0,9,0]] 输出:24 解释: [[0,6,0], [5,8,7], [0,9,0]] 一种收集最多黄金的路线是:9 -> 8 -> 7。
输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]] 输出:28 解释: [[1,0,7], [2,0,6], [3,4,5], [0,3,0], [9,0,20]] 一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。
1 <= grid.length, grid[i].length <= 15
0 <= grid[i][j] <= 100
此题采用 深度优先搜索(DFS) 能够完美解决。毕竟图不是很大。svg
dfs
方法返回的是已开采的最大收益,即开采完当前位置即其周围的单元格后的最大收益。spa
时间复杂度:
空间复杂度:3d
class Solution { int[][] dir = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };// 上下左右 public int getMaximumGold(int[][] grid) { boolean[][] visit = new boolean[grid.length][grid[0].length]; int ret = 0;// 黄金数量 for (int r = 0; r < grid.length; ++r) { for (int c = 0; c < grid[r].length; ++c) { ret = Math.max(ret, dfs(grid, r, c, 0, visit)); } } return ret; } int dfs(int[][] grid, int row, int col, int earn, // 收益,即已开采的黄金数量 boolean[][] visit) { if (row < 0 || row >= grid.length) {// 行越界 return earn; } if (col < 0 || col >= grid[row].length) {// 列越界 return earn; } if (grid[row][col] == 0) {// 当前位置无黄金 return earn; } if (visit[row][col]) {// 已开采过 return earn; } visit[row][col] = true;// 设置当前位置为已开采 earn += grid[row][col];// 收益增长 int ret = earn; for (int[] d : dir) {// 遍历周围的四个方向 int r = row + d[0]; int c = col + d[1]; ret = Math.max(ret, dfs(grid, r, c, earn, visit)); } visit[row][col] = false;// 恢复当前位置 return ret;// 开采当前位置以及周围位置后的最大收益 } }