回溯算法
● 332.重新安排行程
● 51. N皇后
● 37. 解数独
● 总结
重新安排行程
法1:回溯
unordered_map<string,map<string,int>> targets;
//记录机场数:int ticketNum,记录航班:vector<string>ans
bool backTracking(int ticketNum,vector<string>& ans){
if (ticketNum + 1 == ans.size()) {
return true;
}
for (auto &p: targets[ans[ans.size() - 1]]){
if (p.second > 0){
ans.push_back(p.first);
p.second--;
if (backTracking(ticketNum,ans)) return true;
p.second++;
ans.pop_back();
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> ans;
//init targets
targets.clear();
for (const auto &vec: tickets){
targets[vec[0]][vec[1]]++;
}
ans.push_back("JFK");
backTracking(tickets.size(),ans);
return ans;
}
N皇后
51. N皇后
法1: 回溯
vector<vector<string>>ans;
void backTracking(int n,int row,vector<string>& chessBoard){
//终止
if (row == n){
ans.push_back(chessBoard);
return;
}
//单层搜索
for (int col = 0; col < n; ++col) {
if (isVaild(row,col,chessBoard,n)){
//满足N皇后条件
chessBoard[row][col] = 'Q';
backTracking(n,row + 1,chessBoard);
chessBoard[row][col] = '.';
}
}
}
bool isVaild(int row,int col,vector<string>& chessBoard, int n){
//检查列
for (int i = 0; i < row; ++i) {
if (chessBoard[i][col] == 'Q'){
return false;
}
}
//检查45度
for (int i = row - 1,j = col - 1; i >= 0 && j >=0; i--,j--) {
if (chessBoard[i][j] == 'Q'){
return false;
}
}
//检查135度
for (int i = row - 1,j = col + 1; i >= 0 && j < n; i--,j++) {
if (chessBoard[i][j] == 'Q'){
return false;
}
}
return true;
}
vector<vector<string>> solveNQueens(int n) {
ans.clear();
//vector<string> chessBoard;
std::vector<std::string> chessBoard(n, std::string(n, '.'));
backTracking(n,0,chessBoard);
return ans;
}
解数独
法1:回溯
//回溯
bool backTracking(vector<vector<char>>& board){
//遍历行
for (int row = 0; row < board.size(); ++row) {
//遍历列
for (int col = 0; col < board[0].size(); ++col) {
// if (board[row][col] != '.')continue;
if (board[row][col] == '.') {
for (char i = '1'; i <= '9'; ++i) {
//该位置放1-9数字的可能性
if (isVaild(board,i, row, col)) {
//递归
board[row][col] = i;
if (backTracking(board))return true;
//回溯
board[row][col] = '.';
}
}
return false;
}
}
}
return true;
}
bool isVaild(vector<vector<char>>& board, char c,int row, int col){//丢失传过来的字符
//何时返回true??最后所有雷均已躲避
//行有效
for (int i = 0; i < 9; ++i) {
if (board[row][i] == c)return false;
}
//列有效
for (int j = 0; j < 9; ++j) {
if (board[j][col] == c) return false;
}
//九宫格有效 此处需谨慎
int startRow = (row / 3) *3;
int startCol = (col / 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;
}
void solveSudoku(vector<vector<char>>& board) {
backTracking(board);
}