Python 动态规划 实现力扣问题:实现机器人躲避障碍物获取最短路径。
要设计一种算法来寻找机器人从左上角移动到右下角的路径,可以使用动态规划来解决这个问题。下面是一种可能的算法:
- 创建一个处理机器人运动的函数
find_path
,函数接受一个矩阵grid
作为参数,用于表示机器人移动的网格环境,该矩阵一个由 0 和 1 组成的二位列表,其中 0 表示空位置,1 表示障碍物。 - 创建一个大小为
r * c
与网格相同的二维列表dp
,并将起点的路径数目初始化为 1,用于存储从左上角到每个网格点的路径状态,为后面的路径搜索和动态规划求解提供基础。 - 初始化
dp[0][0]
为 1,表示机器人已经位于左上角。 - 遍历第一行和第一列的网格点:
- 如果当前网格点没有障碍物,并且前一个网格点可达,即
dp[i][j-1]
为 1,则将dp[i][j]
设为 1,表示可以从前一个网格点到达当前网格点。 - 否则,将
dp[i][j]
设为 0,表示无法到达当前网格点。
- 如果当前网格点没有障碍物,并且前一个网格点可达,即
- 对于其他的网格点
dp[i][j]
:- 如果当前网格点没有障碍物,并且上方和左方的网格点至少有一个可达,即
dp[i-1][j]
或dp[i][j-1]
至少一个为 1,则将dp[i][j]
设为 1,表示可以从可达的网格点到达当前网格点。 - 否则,将
dp[i][j]
设为 0,表示无法到达当前网格点。
- 如果当前网格点没有障碍物,并且上方和左方的网格点至少有一个可达,即
- 最后,如果
dp[r-1][c-1]
为 1,表示右下角的网格点可达,可以通过回溯从右下角开始,根据dp
数组中的值找到机器人的路径。具体回溯过程如下:- 创建一个空的列表
path
,用于存储路径。 - 将回溯的起点设为右下角的网格点,即将
x
和y
分别设为r - 1
和c - 1
,其中r
和c
分别是网格的行数和列数。 - 进入循环,条件为
x >= 0
和y >= 0
,以确保在网格内部。 - 在每次循环中,将当前位置添加到路径列表
path
中,如果当前位置是左上角的网格点,即x == 0
和y == 0
,则说明已经回溯到起点,跳出循环。否则,检查当前位置的上方的网格点是否可达,即dp[x - 1][y] == 1
,如果可达,则将x
减 1,表示向上移动一格;否则,将y
减 1,表示向左移动一格。 - 循环结束后,路径列表
path
中存储了从左上角到右下角的最短路径中的所有网格点,但是顺序是反过来的,所以需要将其反转。 - 最后,如果右下角的网格点不可达,即
dp[r - 1][c - 1] != 1
,则返回一个空的路径列表。
- 创建一个空的列表
使用上述步骤寻找机器人从左上角移动到右下角的路径其时间复杂度为 O ( r ∗ c ) O(r*c) O(r∗c),其中r
是网格的行数,c
是网格的列数,这是由于在填充dp
列表的过程中,对于每个网格点,都需要访问其上方和左方的网格点,该部分的时间复杂度为 O ( 1 )