leetcode-1219:黄金矿工

简介: leetcode-1219:黄金矿工

题目

题目链接

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。

为了使收益最大化,矿工需要按以下规则来开采黄金:

  • 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
  • 矿工每次可以从当前位置向上下左右四个方向走。
  • 每个单元格只能被开采(进入)一次。
  • 不得开采(进入)黄金数目为 0 的单元格。
  • 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。

示例 1:

输入:grid = [[0,6,0],[5,8,7],[0,9,0]]
输出:24
解释:
[[0,6,0],
 [5,8,7],
 [0,9,0]]
一种收集最多黄金的路线是:9 -> 8 -> 7。
• 1
• 2
• 3
• 4
• 5
• 6
• 7

示例 2:

输入: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
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9

解题

方法一:回溯

参考链接

写法一

将sum作为参数进行传参(由于局部变量的关系,自动起到回溯的效果)

class Solution {
public:
    int res=0;
    vector<vector<int>> dirs={{-1,0},{1,0},{0,1},{0,-1}};                                   
    int getMaximumGold(vector<vector<int>>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        vector<vector<bool>> visit(m,vector<bool>(n,false));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]!=0){
                    visit[i][j]=true;
                    backtracing(grid,visit,grid[i][j],i,j);
                    visit[i][j]=false;
                }
            }
        }
        return res;
    }
    void backtracing(vector<vector<int>>& grid,vector<vector<bool>>& visit,int sum,int x,int y){
        res=max(res,sum);
        for(vector<int>& dir:dirs){
            int nx=x+dir[0];
            int ny=y+dir[1];
            if(nx<0||nx>=grid.size()||ny<0||ny>=grid[0].size()||visit[nx][ny]==true||grid[nx][ny]==0) continue;
            visit[nx][ny]=true;
            backtracing(grid,visit,sum+grid[nx][ny],nx,ny);
            visit[nx][ny]=false;
        }  
    }   
};
• 1
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9
• 10
• 11
• 12
• 13
• 14
• 15
• 16
• 17
• 18
• 19
• 20
• 21
• 22
• 23
• 24
• 25
• 26
• 27
• 28
• 29
• 30
• 31

写法二

另外声明一个变量path作为过程,不进行传参,要手动+或-

class Solution {
public:
    int res=0;
    int path=0;    
    vector<vector<int>> dirs={{-1,0},{1,0},{0,1},{0,-1}};                                   
    int getMaximumGold(vector<vector<int>>& grid) {
        int m=grid.size();
        int n=grid[0].size();
        vector<vector<bool>> visit(m,vector<bool>(n,false));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]!=0){
                    path=grid[i][j];
                    res=max(path,res);//注意一定要单独比较,否则如果都是单独的起始点,就会失败
                    visit[i][j]=true;
                    backtracing(grid,visit,i,j);
                    visit[i][j]=false;
                }
            }
        }
        return res;
    }
    void backtracing(vector<vector<int>>& grid,vector<vector<bool>>& visit,int x,int y){
        for(vector<int>& dir:dirs){
            int nx=x+dir[0];
            int ny=y+dir[1];
            if(nx<0||nx>=grid.size()||ny<0||ny>=grid[0].size()||visit[nx][ny]==true||grid[nx][ny]==0) continue;
            path+=grid[nx][ny];
            res=max(res,path);
            visit[nx][ny]=true;
            backtracing(grid,visit,nx,ny);
            visit[nx][ny]=false;
            path-=grid[nx][ny];
        }  
    }   
};
• 1
• 2
• 3
• 4
• 5
• 6
• 7
• 8
• 9
• 10
• 11
• 12
• 13
• 14
• 15
• 16
• 17
• 18
• 19
• 20
• 21
• 22
• 23
• 24
• 25
• 26
• 27
• 28
• 29
• 30
• 31
• 32
• 33
• 34
• 35
• 36

相关文章
|
2月前
|
机器学习/深度学习 算法
力扣刷题日常(一)
力扣刷题日常(一)
20 2
|
2月前
|
存储 索引
《LeetCode》—— LeetCode刷题日记
《LeetCode》—— LeetCode刷题日记
|
2月前
|
搜索推荐
《LeetCode》——LeetCode刷题日记3
《LeetCode》——LeetCode刷题日记3
|
2月前
|
容器
《LeetCode》——LeetCode刷题日记1
《LeetCode》——LeetCode刷题日记1
|
2月前
|
算法
LeetCode刷题---21.合并两个有序链表(双指针)
LeetCode刷题---21.合并两个有序链表(双指针)
|
2月前
|
算法
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
LeetCode刷题---19. 删除链表的倒数第 N 个结点(双指针-快慢指针)
|
2月前
|
算法 测试技术
LeetCode刷题--- 430. 扁平化多级双向链表(深度优先搜索)
LeetCode刷题--- 430. 扁平化多级双向链表(深度优先搜索)
|
2月前
|
存储
实现单链表的基本操作(力扣、牛客刷题的基础&笔试题常客)
实现单链表的基本操作(力扣、牛客刷题的基础&笔试题常客)
144 38
|
10天前
刷题之Leetcode160题(超级详细)
刷题之Leetcode160题(超级详细)
11 0

热门文章

最新文章