332. 重新安排行程
class Solution {
private:
// 数据结构至关重要
// unordered_map<出发机场, map<到达机场, 航班次数>>
unordered_map<string, map<string, int>> targets_;
vector<string> path_;
int ticket_size_ = 0;
public:
bool backTracking() {
if (path_.size() == ticket_size_ + 1) {
return true;
}
for (auto &target : targets_[path_[path_.size() - 1]]) {
if (target.second > 0) {
path_.push_back(target.first);
target.second--;
if (backTracking()) return true;
target.second++;
path_.pop_back();
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
ticket_size_ = tickets.size();
for (const auto &ticket : tickets) {
targets_[ticket[0]][ticket[1]]++;
}
path_.push_back("JFK");
backTracking();
return path_;
}
};
51. N 皇后
class Solution {
private:
vector<vector<string>> ret_;
vector<string> chess_board_;
public:
bool isValid(int row, int col, int n) {
// 检查列
for (int i = row - 1; i >= 0; i--) {
if (chess_board_[i][col] == 'Q') return false;
}
// 检查45度
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (chess_board_[i][j] == 'Q') return false;
}
// 检查135度
for (int i = row - 1, j = col + 1; i >= 0 && j <= n-1; i--, j++) {
if (chess_board_[i][j] == 'Q') return false;
}
return true;
}
void backTracking(int n , int row){
if (row == n) {
ret_.push_back(chess_board_);
return;
}
// 递归控制行,for循环控制列
for (int col = 0; col < n; col++) {
if (isValid(row, col, n)) {
chess_board_[row][col] = 'Q';
backTracking(n, row + 1);
chess_board_[row][col] = '.';
}
}
}
vector<vector<string>> solveNQueens(int n) {
chess_board_.resize(n, string(n, '.'));
backTracking(n ,0);
return ret_;
}
};
37. 解数独
class Solution {
// 每次确认一个位置,都需要双层遍历
public:
bool isVaild(vector<vector<char>>& board, int row, int col, char target_num) {
// 检查行
for (int i = 0; i < board.size(); i++) {
if (board[i][col] == target_num) return false;
}
// 检查列
for (int i = 0; i < board.size(); i++) {
if (board[row][i] == target_num) return false;
}
// 检查3x3
int row_index = (row / 3) * 3;
int col_index = (col / 3) * 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[row_index + i][col_index + j] == target_num) return false;
}
}
return true;
}
bool backTracking(vector<vector<char>>& board) {
// 递归处理
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board.size(); j++) {
// 已填充数字不用处理
if (board[i][j] != '.') continue;
// 检查哪个数字可填充
for (char num = '1'; num <= '9'; num++) {
if (isVaild(board, i, j, num)) {
board[i][j] = num;
if (backTracking(board)) return true;
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backTracking(board);
}
};