LeetCode刷题--- 不同路径 III

个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客

个人专栏

力扣递归算法题

 http://t.csdnimg.cn/yUl2I

【C++】    

​​​​​​http://t.csdnimg.cn/6AbpV

数据结构与算法

 ​​​http://t.csdnimg.cn/hKh2l


前言:这个专栏主要讲述递归递归、搜索与回溯剪枝算法,所以下面题目主要也是这些算法做的  

我讲述题目会把讲解部分分为3个部分:
1、题目解析

2、算法原理思路讲解

3、代码实现


不同路径 III

题目链接:不同路径 III

题目

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

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

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

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

示例 1:

输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)

示例 2:

输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]]
输出:4
解释:我们有以下四条路径: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)

示例 3:

输入:[[0,1],[2,0]]
输出:0
解释:
没有一条路能完全穿过每一个空的方格一次。
请注意,起始和结束方格可以位于网格中的任意位置。

提示:

  • 1 <= grid.length * grid[0].length <= 20

解法

题目解析

  • 1 表示起始方格。且只有一个起始方格。
  • 2 表示结束方格,且只有一个结束方格。
  • 0 表示我们可以走过的空方格。
  • -1 表示我们无法跨越的障碍。
  • 返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目
  • 每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格

算法原理思路讲解

设计代码

(1)全局变量

bool visit[20][20];
int ret;
int step;
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { 1, -1, 0, 0 };
  • ret(用于记录符合的次数)
  • step(所有的步数和)
  • visit(二位数组中的元素是否被用过)
  • dx[4](用于计算)
  • dy[4](用于计算)

(2)设计递归函数

void dfs(vector>& grid, int x, int y, int path);
  • 参数:x(当前需要进⾏处理的元素横坐标),y(当前需要进⾏处理的元素横坐标),path(当前已经处理的步数和);
  • 返回值:无 ;
  • 函数作用:判断当前位置的四个⽅向是否可以添加⾄当前状态,查找在满⾜条件下从起始⽅格到结束⽅格的不同路径的数⽬。

代码实现

class Solution {
public:
bool visit[20][20];
int ret;
int step;
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { 1, -1, 0, 0 };

    void dfs(vector>& grid, int x, int y, int path)
    {
        if (grid[x][y] == 2)
        {
            if (path == step)
            {
                ret++;
            }
            return;
        }

        int m = grid.size();
        int n = grid[0].size();

        for (int i = 0; i < 4; i++)
        {
            int x1 = x + dx[i];
            int y1 = y + dy[i];

            if (x1 >= 0 && x1 < m && y1 >= 0 && y1 < n && !visit[x1][y1] && grid[x1][y1] != -1)
            {
                visit[x1][y1] = true;
                dfs(grid, x1, y1, path + 1);
                visit[x1][y1] = false;
            }
        }

    }
    int uniquePathsIII(vector>& grid) 
    {
        int x = 0;
        int y = 0;

        for (int i = 0; i < grid.size(); i++)
        {
            for (int j = 0; j < grid[0].size(); j++)
            {
                if (grid[i][j] == 0)
                {
                    step++;
                }
                else if (grid[i][j] == 1)
                {
                    x = i;
                    y = j;
                }
            }
        }

        step += 2;
        visit[x][y] = true;
        dfs(grid, x, y, 1);

        return ret;
    }
};

LeetCode刷题--- 不同路径 III_第1张图片

你可能感兴趣的:(力扣递归算法题,leetcode,算法)