《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
题中隐含的假设是只有一条从左上角到右下角的路径,否则添加的节点中将包含所有路径的节点。递归算法从终结点开始从其左节点和上节点出发检查是否有一条从开始节点(左上角的节点)到达终结点的左节点或上节点的路径。递归该过程直到到达左上角的源节点为止,所得路径即为所求。
改进算法记录每次被访问过的节点避免下一次的重复访问来提高时间效率。
//递归法
bool getPath(vector<vector<bool>> &maze,int row,int column, vector<pair<int, int>> *path)
{
if (row < 0 || column < 0 || !maze[row][column])
return false;
bool isAtOrigin = (row == 0) && (column == 0);
if (isAtOrigin || getPath(maze, row, column - 1, path) || getPath(maze, row - 1, column, path))
{
path->push_back(pair<int, int>(row, column));
return true;
}
return false;
}
vector<pair<int, int>>* getPath(vector<vector<bool>> maze)
{
if (maze.size() == 0)
return nullptr;
vector<pair<int, int>>* path = new vector<pair<int, int>>;
if (getPath(maze, maze.size()-1, maze[0].size()-1, path))
{
return path;
}
return nullptr;
}
//改进的递归法
bool getPath(vector<vector<bool>> &maze,int row,int column, vector<pair<int, int>> *path, set<pair<int, int>> *failedPoints)
{
if (row < 0 || column < 0 || !maze[row][column])
return false;
pair<int,int> currentPair = { row,column };
if (failedPoints->find(currentPair) == failedPoints->end)
{
return false;
}
bool isAtOrigin = (row == 0) && (column == 0);
if (isAtOrigin || getPath(maze, row, column - 1, path, failedPoints) || getPath(maze, row - 1, column, path, failedPoints))
{
path->push_back(pair<int, int>(row, column));
return true;
}
failedPoints->insert(pair<int, int>(row, column));
return false;
}
vector<pair<int, int>>* getPath(vector<vector<bool>> maze)
{
if (maze.size() == 0)
return nullptr;
vector<pair<int, int>>* path = new vector<pair<int, int>>;
set<pair<int, int>> *failedPoints=new set<pair<int, int>>;
if (getPath(maze, maze.size()-1, maze[0].size()-1, path, failedPoints))
{
return path;
}
return nullptr;
}