你要開發一座金礦,地質勘測學家已經探明瞭這座金礦中的資源分佈,並用大小爲 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;// 開採當前位置以及周圍位置後的最大收益 } }