题目概述
解题思路
参考了题解的做法,我们采用广度优先搜索的方式来解决问题。题目中说到,我们可以破坏至多K个障碍,所以我们在做搜索的时候,需要维护除了当前节点坐标(x, y)之外的另一维度的信息,就是当前剩余的破坏障碍的次数C。我们的目标就是,在C变为负值前,从(0, 0)出发能访问到(M - 1, N - 1)。由于是广度优先搜索,我们第一次访问到该节点时,走过的距离就是最短路径。
方法的时间复杂度是O(MNK)。
方法性能
示例代码
class Nodes
{
public:
int x, y, rest, steps;
Nodes(int xi, int yi, int resti, int si): x(xi), y(yi), rest(resti), steps(si) {}
};
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
class Solution {
public:
int shortestPath(vector<vector<int>>& grid, int k)
{
int R_len = grid.size(),
C_len = grid[0].size();
if(R_len == 1 && C_len == 1)
return 0;
queue<Nodes> bfs;
bool vis[R_len][C_len][k + 1];
memset(vis, false, sizeof(vis));
bfs.push(Nodes(0, 0, k, 0));
while(bfs.size())
{
Nodes temp = bfs.front();
bfs.pop();
for (int di = 0, xi, yi; di < 4; ++di)
{
xi = temp.x + dir[di][0];
yi = temp.y + dir[di][1];
//check the visibility of nodes
if(xi < 0 || xi >= R_len || yi < 0 || yi >= C_len)
continue;
//check if we are at the target node
if(xi == R_len - 1 && yi == C_len - 1)
return temp.steps + 1;
//check if we can visit this node with cost
if(temp.rest < grid[xi][yi])
continue;
//check the visiting history of node
if(vis[xi][yi][temp.rest - grid[xi][yi]])
continue;
bfs.push(Nodes(xi, yi, temp.rest - grid[xi][yi], temp.steps + 1));
vis[xi][yi][temp.rest - grid[xi][yi]] = true;
}
}
return -1;
}
};
其实我们无需存储节点的步长,不过这时我们需要写一个循环,以确保当前步长的所有节点都已经被遍历过。
class Nodes
{
public:
int x, y, rest;
Nodes(int xi, int yi, int resti): x(xi), y(yi), rest(resti) {}
};
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
class Solution {
public:
int shortestPath(vector<vector<int>>& grid, int k)
{
int R_len = grid.size(),
C_len = grid[0].size(),
layer_len = 1, STEP = 0;
if(R_len == 1 && C_len == 1)
return 0;
queue<Nodes> bfs;
bool vis[R_len][C_len][k + 1];
memset(vis, false, sizeof(vis));
bfs.push(Nodes(0, 0, k));
while(bfs.size())
{
layer_len = bfs.size();
STEP++;
for (int li = 0; li < layer_len;++li)
{
Nodes temp = bfs.front();
bfs.pop();
for (int di = 0, xi, yi; di < 4; ++di)
{
xi = temp.x + dir[di][0];
yi = temp.y + dir[di][1];
//check the visibility of nodes
if(xi < 0 || xi >= R_len || yi < 0 || yi >= C_len)
continue;
//check if we are at the target node
if(xi == R_len - 1 && yi == C_len - 1)
//return temp.steps + 1;
return STEP;
//check if we can visit this node with cost
if(temp.rest < grid[xi][yi])
continue;
//check the visiting history of node
if(vis[xi][yi][temp.rest - grid[xi][yi]])
continue;
bfs.push(Nodes(xi, yi, temp.rest - grid[xi][yi]));
vis[xi][yi][temp.rest - grid[xi][yi]] = true;
}
}
}
return -1;
}
};