Leetcode-不同路径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数组先遍历找出起点的位置:

for i in range(len(grid)):
    for j in range(len(grid[0])):
        if grid[i][j]==1:
            x,y=i,j
  1. 每一个无障碍方格都要通过一次

所以要统计无障碍方格的数量,在上一个循环中顺便统计即可,得到maxNum

  1. 终止递归条件:首先搜索到终点,如果经过的方格数=无障碍方格数+1(终点),则终止递归条件,反之也终止递归

坐标的不断搜索可以采用以下函数:

dirs=[(0,-1),(0,1),(-1,0),(1,0)]
  1. 主体DFS部分:

def DFS(x,y,num):
    if grid[x][y]==2:
        if num==maxNum+1:
            result+=1
            return
        else:return
    for dir in dirs:
        if 0<=x+dir[0]

这里需要解释几点,首先visited是深搜标配,表示有无经过(i,j)这一点,而且还需要满足下一个目的地无障碍物且在grid范围中,才能往下搜索

全部代码:

class Solution:
    def uniquePathsIII(self, grid) -> int:
        m,n=len(grid),len(grid[0])
        maxNum=0
        for i in range(m):
            for j in range(n):
                if grid[i][j]==1:
                    x,y=i,j
                if grid[i][j]==0:
                    maxNum+=1
        visited=[[False for i in range(n)] for j in range(m)]
        result=0
        def DFS(x,y,num):
            nonlocal result,visited
            dirs=[(0,-1),(0,1),(-1,0),(1,0)]
            if grid[x][y]==2:
                if num==maxNum+1:
                    result+=1
                else:return
            for dir in dirs:
                if 0<=x+dir[0]

考虑到重新创建并遍历visited太耗时间,故可以在回溯过程中直接在grid中进行修改,那么:

visited[x][y]=True等价于grid[x][y]=-1
visited[x][y]==False等价于grid[x][y]!=-1

故最终代码:

class Solution:
    def uniquePathsIII(self, grid) -> int:
        m,n=len(grid),len(grid[0])
        maxNum=0
        for i in range(m):
            for j in range(n):
                if grid[i][j]==1:
                    x,y=i,j
                if grid[i][j]==0:
                    maxNum+=1
        result=0
        def DFS(x,y,num):
            nonlocal result
            dirs=[(0,-1),(0,1),(-1,0),(1,0)]
            if grid[x][y]==2:
                if num==maxNum+1:
                    result+=1
                    return
                else:return
            for dir in dirs:
                if 0<=x+dir[0]

你可能感兴趣的:(leetcode,算法,职场和发展)