坐在NxN网格左上角的机器人。机器人只能在两个方向上移动:向右和向下,其中一些单元格已经死亡,即机器人无法进入该单元格。机器人有多少可能的路径?
这可以使用Backtracking来解决,但它的时间复杂度太高。我使用回溯解决了这个问题,但在更糟的情况下需要O(2 ^ n)。
bool exist(bool a[][], int i, int j,int N){
return i>=0 && j >=0 && i < N && j < N;
}
int search(bool a[][], int i, int j,int N){
if(!exist(a,i,j,N) || a[i][j] == 1)
return 0; // no path here.
if(i == N-1 && j == N - 1){
return 1; // 1 path here.
}
a[i][j] = 1; // mark that we have seen this spot here
int paths = 0; // introduce a counter...
paths += search(a, i,j+1,N); // add the additional paths as we find them
paths += search(a, i+1,j,N);
a[i][j] = 0;
return paths; // return the number of paths available from this point.
}
此处带有1的单元格表示死区。是否可以通过使用DFS或动态编程e.t.c来降低时间复杂度?
答案 0 :(得分:1)
这可以通过识别到特定节点的路径数量只是到左边节点的路径数量和到上面节点的路径数量之和来解决。您只需要提出一个算法来按正确的顺序处理节点,即只在其父母&#34;父母&#34;之后处理节点。已经处理完毕。我相信这可能是O(n)。
答案 1 :(得分:1)
让我们假设以下3x3网格,其中网格中的1表示障碍
[0,0,0]
[0,1,0]
[0,0,0]
在这种情况下,唯一路径的数量是2。 我们可以使用动态编程方法来减少时间复杂度,找到唯一路径,这里是C ++中相同的代码
int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector<vector<int> > arr(m,vector<int>(n,0));
if (obstacleGrid[0][0]==1){return 0;}
arr[0][0]=1;
for (int i=1;i<m;i++){
if (obstacleGrid[i][0]!=1){
arr[i][0] = arr[i-1][0];
}
}
for (int i=1;i<n;i++){
if (obstacleGrid[0][i]!=1){
arr[0][i] = arr[0][i-1];
}
}
for (int i=1;i<m;i++){
for(int j=1;j<n;j++){
if (obstacleGrid[i][j]!=1){
arr[i][j] = arr[i][j-1] + arr[i-1][j];
}
}
}
return arr[m-1][n-1];
}
这种情况下的时间复杂度为O(mn)。
答案 2 :(得分:0)
如果有NxN grid
,请ways[i][j] = number of possible paths from grid[0][0] to grid[i][j]
初始化grid[0][0] = 1
如果grid[i][j] is dead
,ways[i][j] = 0
else ways[i][j] = ways[i-1][j] + ways[i][j-1]
(但要注意边缘)
一个例子:
grid:(1 means dead) ways:
0 0 1 0 0 1 1 0 0 0
0 0 0 0 0 1 2 2 2 2
0 1 0 0 1 1 0 2 4 0
1 0 0 0 0 0 0 2 6 6
0 0 0 0 0 0 0 2 8 14
我认为复杂度为O(n^2)
,因为有n*n
网格。