• 递归算法学习——黄金矿工,不同路径III


    目录

    ​编辑

    一,黄金矿工

    1.题意

    2.题目分析

    3.题目接口

    4.解题思路及代码

    二,不同路径III

    1.题意

    2.解释

    3.题目接口

     4.解题思路及代码


     

    一,黄金矿工

    1.题意

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

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

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

    2.题目分析

    这道题要我们做的便是找到一条路径,在这条路径上我们能够收集到的黄金的数量是最多的。在这道题里面还有一个前提便是当遇到数字为0的空格时便不能走这一条路径了。

    3.题目接口

    1. class Solution {
    2. public:
    3. int getMaximumGold(vectorint>>& grid) {
    4. }
    5. };

    4.解题思路及代码

    先来写个代码:

    1.第一种写法

    1. class Solution {
    2. public:
    3. int m,n;
    4. int path;//表示每一条路径上的黄金数量
    5. int sum;//记录最大和
    6. int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};//坐标法表示坐标的上下左右移动
    7. int getMaximumGold(vectorint>>& grid) {
    8. m = grid.size(),n = grid[0].size();
    9. for(int i = 0;i
    10. {
    11. for(int j = 0;j
    12. {
    13. if(grid[i][j]!=0)//当找到不是0的位置时便可以从这个位置开始递归找结果
    14. {
    15. path = grid[i][j];
    16. int remark = grid[i][j];
    17. grid[i][j]=0;//该位置被寻找了以后便要将该位置置为0
    18. dfs(grid,i,j);
    19. grid[i][j] = remark;
    20. path-=remark;
    21. }
    22. }
    23. }
    24. return sum;
    25. }
    26. void dfs(vectorint>>&grid,int i,int j)
    27. {
    28. sum = max(sum,path);//找到sum与path中的较大值
    29. for(int k = 0;k<4;k++)
    30. {
    31. int x = i+dx[k],y = j+dy[k];
    32. if(x>=0&&x=0&&y0)
    33. {
    34. path+=grid[x][y];
    35. int temp = grid[x][y];
    36. grid[x][y] = 0;
    37. dfs(grid,x,y);
    38. path-=temp;
    39. grid[x][y] = temp;
    40. }
    41. }
    42. }
    43. };

    其实这道题的解法和我们之前写的矩阵深搜问题的解题代码是差不多的。小小的不同点便是要比较较大值来对sum进行更新。为了避免麻烦我们便用max在每一次进入递归时就比较一下对sum更新一下,以此来确保sum是最大值

    2.第二种写法

    在上面的写法中我们使用的是全局变量path和修改原来的矩阵的方式来标记查找过的位置,在这里我们写一种不同的解法:

    1. class Solution {
    2. public:
    3. int m,n;
    4. int sum;
    5. bool used[15][15];//用相同大小的used数组来标记使用过的位置。
    6. int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
    7. int getMaximumGold(vectorint>>& grid) {
    8. m = grid.size(),n = grid[0].size();
    9. for(int i = 0;i
    10. {
    11. for(int j = 0;j
    12. {
    13. if(grid[i][j]!=0)
    14. {
    15. used[i][j] = true;
    16. dfs(grid,i,j,grid[i][j]);
    17. used[i][j] = false;
    18. }
    19. }
    20. }
    21. return sum;
    22. }
    23. void dfs(vectorint>>&grid,int i,int j,int path)
    24. {
    25. sum = max(sum,path);
    26. for(int k = 0;k<4;k++)
    27. {
    28. int x = i+dx[k],y = j+dy[k];
    29. if(x>=0&&x=0&&y0&&!used[x][y])
    30. {
    31. used[x][y] = true;
    32. dfs(grid,x,y,path+grid[x][y]);
    33. used[x][y] = false;
    34. }
    35. }
    36. }
    37. };

    二,不同路径III

    1.题意

    在二维网格 grid 上,有 4 种类型的方格:

    • 1 表示起始方格。且只有一个起始方格。
    • 2 表示结束方格,且只有一个结束方格。
    • 0 表示我们可以走过的空方格。
    • -1 表示我们无法跨越的障碍。

    返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目

    每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格

    2.解释

    这道题要我们做的便是在将数值为0的空格遍历完了以后到达数值为2的空格的路径有几条。还是深度优先搜索的问题。在这道题里数值为-1的格子是一个障碍物,不能去遍历。并且,每个空格只能遍历一次。

    3.题目接口

    1. class Solution {
    2. public:
    3. int uniquePathsIII(vectorint>>& grid) {
    4. }
    5. };

     4.解题思路及代码

    先写代码:

    1. class Solution {
    2. public:
    3. int count ;//记录路径的个数
    4. int step;//记录要走的步数
    5. int num ;//记录当前走了多少步
    6. int m,n;
    7. bool used[20][20];
    8. int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
    9. int uniquePathsIII(vectorint>>& grid) {
    10. m = grid.size();
    11. n = grid[0].size();
    12. int beginx,beginy;
    13. for(int i = 0;i
    14. {
    15. for(int j = 0;j
    16. {
    17. if(grid[i][j]==0)
    18. {
    19. step++;//找到0的个数
    20. }
    21. if(grid[i][j] == 1)//记录入口的下标
    22. {
    23. beginx = i;
    24. beginy = j;
    25. }
    26. }
    27. }
    28. step+=1;//算上2这一步
    29. used[beginx][beginy] = true;
    30. dfs(grid,beginx,beginy);
    31. return count;
    32. }
    33. void dfs(vectorint>>&grid,int i,int j)
    34. {
    35. if(num == step)
    36. {
    37. if(grid[i][j] == 2)
    38. {
    39. count++;
    40. }
    41. return;
    42. }
    43. for(int k = 0;k<4;k++)
    44. {
    45. int x = i+dx[k],y = j+dy[k];
    46. if(x>=0&&x=0&&y-1&&!used[x][y])
    47. {
    48. num++;
    49. used[x][y] = true;
    50. dfs(grid,x,y);
    51. num--;
    52. used[x][y] = false;
    53. }
    54. }
    55. }
    56. };

    样子还是和之前的题目的的解题代码相像但是在这里就要一个主动的递归出口了,也就是当所有的0都被遍历完了以后到了2这一步就得到了一个结果了。

  • 相关阅读:
    vue:对三种获取更新后的dom的方式进行分析
    Redis笔记
    HTTP/HTTPS | 青训营笔记
    Linux文件权限修改
    重识babel 7
    【超好懂的比赛题解】2022CCPC四川省赛 个人题解
    kubeadm安装k8s高可用集群
    山西电力市场日前价格预测【2023-09-21】
    c#winform窗体
    【JS学习】字符串的replace方法
  • 原文地址:https://blog.csdn.net/qq_41934502/article/details/132734205