Day 30 回溯算法
332. 重新安排行程
想了很久,最后还是放弃了
这道题目有几个难点:
- 一个行程中,如果航班处理不好容易变成一个圈,成为死循环
- 有多种解法,字母序靠前排在前面,让很多同学望而退步,如何该记录映射关系呢 ?
- 使用回溯法(也可以说深搜) 的话,那么终止条件是什么呢?
- 搜索的过程中,如何遍历一个机场所对应的所有机场
这一题的解法也非常考验对数据结构的运用文章来源:https://www.toymoban.com/news/detail-527767.html
class Solution {
unordered_map<string, map<string, int>> table;
bool backtracking(int ticketNum, vector<string> &path)
{
if (path.size() > ticketNum)
{
return true;
}
for (auto &[to, num] : table[path.back()])
{
if (num)
{
num--;
path.push_back(to);
if (backtracking(ticketNum, path))
{
return true;
}
path.pop_back();
num++;
}
}
return false;
}
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
table.clear();
for (const auto &ticket : tickets)
{
table[ticket[0]][ticket[1]]++;
}
vector<string> path;
path.push_back("JFK");
backtracking(tickets.size(), path);
return path;
}
};
51. N皇后
class Solution {
vector<vector<string>> rst;
bool isValid(const vector<string> chessBoard, int row, int col)
{
int n = chessBoard.size();
for (int i = row - 1; i >= 0; i--)
{
if (chessBoard[i][col] == 'Q')
{
return false;
}
}
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++)
{
if (chessBoard[i][j] == 'Q')
{
return false;
}
}
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
{
if (chessBoard[i][j] == 'Q')
{
return false;
}
}
return true;
}
void backtracking(vector<string> &chessBoard, int curRow)
{
int n = chessBoard.size();
if (curRow == n)
{
rst.push_back(chessBoard);
return;
}
for (int i = 0; i < n; ++i)
{
if (isValid(chessBoard, curRow, i))
{
chessBoard[curRow][i] = 'Q';
backtracking(chessBoard, curRow + 1);
chessBoard[curRow][i] = '.';
}
}
}
public:
vector<vector<string>> solveNQueens(int n) {
rst.clear();
vector<string> chessBoard(n, string(n, '.'));
backtracking(chessBoard, 0);
return rst;
}
};
37. 解数独
大概有思路,但是实现起来,还是容易卡在回溯的模板里,这道题其实不是完全照搬回溯的模板就能解决的,有一点差异。文章来源地址https://www.toymoban.com/news/detail-527767.html
class Solution {
bool isValid(const vector<vector<char>> &board, int curRow, int curCol, char c)
{
for (int i = 0; i < 9; ++i)
{
if (board[i][curCol] == c || board[curRow][i] == c)
{
return false;
}
}
int startRow = curRow / 3 * 3;
int startCol = curCol / 3 * 3;
for (int i = startRow; i < startRow + 3; ++i)
{
for (int j = startCol; j < startCol + 3; ++j)
{
if (board[i][j] == c)
{
return false;
}
}
}
return true;
}
bool backtracking(vector<vector<char>> &board)
{
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
{
if (board[i][j] == '.')
{
for (char num = '1'; num <= '9'; num++)
{
if (isValid(board, i, j, num))
{
board[i][j] = num;
if (backtracking(board))
{
return true;
}
board[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
public:
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};
到了这里,关于算法刷题Day 30 重新安排行程+N皇后+解数独的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!