设想有个机器人坐在一个网格的左上角,网格 r 行 c 列。机器人只能向下或向右移动,但不能走到一些被禁止的网格(有障碍物)。设计一种算法,寻找机器人从左上角移动到右下角的路径。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/robot-in-a-grid-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
————————
解题思路:
(1)首先判断机器人能否到达终点,从终点开始往机器人方向前行,每次只能向上或者向左走一步,将从终点到起点的所有能走通的位置标记为2。
(2)从起点向下或者向右选择位置数据为2的点进行前进,每次将位置索引放进列表中,直到到达终点。
具体C++代码如下:
class Solution:
def pathWithObstacles(self, obstacleGrid: List[List[int]]) -> List[List[int]]:
if not obstacleGrid: # 如果地图为空,则返回空列表
return []
rows = len(obstacleGrid) # 计算地图长度
cols = len(obstacleGrid[0])
if obstacleGrid[0][0]==1 or obstacleGrid[rows-1][cols-1]==1: # 如果起点和终点是障碍,直接返回
return []
obstacleGrid[rows-1][cols-1] = 2 # 将终点作为起点,标记为2,表示可以到达
for i in range(rows-2,-1,-1): # 判断最后一列,从下往上终点能够到达的地方
if obstacleGrid[i+1][cols-1] == 2 and obstacleGrid[i][cols-1]!=1:
obstacleGrid[i][cols-1] = 2
for i in range(cols-2,-1,-1): # 判断最后一行,从右往左终点能到达的最远位置
if obstacleGrid[rows-1][i+1] == 2 and obstacleGrid[rows-1][i]!=1:
obstacleGrid[rows-1][i] = 2
for i in range(rows-2,-1,-1): # 判断能否从终点返回起点
for j in range(cols-2,-1,-1):
if (obstacleGrid[i+1][j]==2 or obstacleGrid[i][j+1]==2) and obstacleGrid[i][j]!=1:
obstacleGrid[i][j] = 2
if obstacleGrid[0][0]!=2: # 如果起点的数值不是2,说明终点不能返回起点,障碍物挡住了,返回空列表
return []
nr = 0
nc = 0
index = [[nr,nc]] # 从起点搜索到终点,看该点下面或右边是否存在值为2的点
while nr<rows and nc<cols:
if nr+1<rows and obstacleGrid[nr+1][nc]==2:
index.append([nr+1,nc])
nr+=1
elif nc+1<cols and obstacleGrid[nr][nc+1]==2:
index.append([nr,nc+1])
nc+=1
else: # 如果其右边或者下面都不是2,说明障碍物挡住了,直接结束循环
break
if nr==rows-1 and nc==cols-1: # 如果可以到达终点,返回列表路径
return index
return [] # 否则返回空列表