1219. Path with Maximum Gold
问题:
给定一个二维数组表示藏金矿地图,每个cell表示所在位置藏有的金矿量,
求从任意一个cell开始走地图,不走走过的cell,不走金矿量=0的cell,只能从当前cell的上下左右四个方向进行下一步移动。
最终能获得的最大金矿量。
Example 1: Input: grid = [[0,6,0],[5,8,7],[0,9,0]] Output: 24 Explanation: [[0,6,0], [5,8,7], [0,9,0]] Path to get the maximum gold, 9 -> 8 -> 7. Example 2: Input: grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]] Output: 28 Explanation: [[1,0,7], [2,0,6], [3,4,5], [0,3,0], [9,0,20]] Path to get the maximum gold, 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7. Constraints: 1 <= grid.length, grid[i].length <= 15 0 <= grid[i][j] <= 100 There are at most 25 cells containing gold.
解法:Backtracking(回溯算法)
状态:走到当前位置(i,j)所获得的金矿量path,和标记了已经走过的路径visited。
选择:上下左右四个方向:除去:超过边界 || 已经走过visited=true || 金矿为0grid[i][j]=0
退出递归条件:当前位置不可走,满足👆 除去条件。
代码参考:
1 class Solution { 2 public: 3 int m=0,n=0; 4 bool isValid(vector<vector<int>>& grid, int i, int j, vector<vector<bool>>& visited) { 5 if(i < 0 || i >= n || j < 0 || j >= m || grid[i][j] == 0 || visited[i][j] == true) { 6 return false; 7 } else return true; 8 } 9 void backtrack(int& res, int& path, int i, int j, vector<vector<int>>& grid, vector<vector<bool>>& visited) { 10 if(isValid(grid, i, j, visited)==false) { 11 res = max(res, path); 12 return; 13 } 14 path += grid[i][j]; 15 visited[i][j] = true; 16 backtrack(res, path, i+1, j, grid, visited); 17 backtrack(res, path, i, j+1, grid, visited); 18 backtrack(res, path, i-1, j, grid, visited); 19 backtrack(res, path, i, j-1, grid, visited); 20 path -= grid[i][j]; 21 visited[i][j] = false; 22 return; 23 } 24 int getMaximumGold(vector<vector<int>>& grid) { 25 int res=0, path=0; 26 n = grid.size(); 27 m = grid[0].size(); 28 vector<vector<bool>> visited(n, vector<bool>(m,false)); 29 for(int i=0; i<n; i++) { 30 for(int j=0; j<m; j++) { 31 if(grid[i][j]!=0) { 32 backtrack(res, path, i, j, grid, visited); 33 } 34 } 35 } 36 return res; 37 } 38 };
♻️ 优化:
省去visited标记已走过的路径,直接将grid当前cell赋值为0(记得return前,恢复)