class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> res;
//记录所有站点作为起始航班到其他航班的机票数
for(const vector<string> &vec:tickets){
targets[vec[0]][vec[1]]++;
}
res.push_back("JFK");
//因为不能有重复的机票,所以tickets.size()是所有机票数,站点数=机票数+1
backtracking(tickets.size(),res);
return res;
}
private:
// unordered_map<出发机场, map<到达机场, 航班次数>> targets
// unordered_map无序,map有序,所以在选择机场时按照字典顺序
unordered_map<string,map<string,int>> targets;
bool backtracking(int ticketNum,vector<string> &res){
if(res.size()==ticketNum+1){
//对啊这里可以计算一下所有地点的数量
return true;
}
// 寻找当前路径res的最后一个站点的起点机票
for(pair<const string,int> &target:targets[res[res.size()-1]]){
// 如果有机票就飞过去,继续遍历
if(target.second>0){
res.push_back(target.first);
target.second--;
// 飞过去之后,剩下的机票如果能用完,返回true
if(backtracking(ticketNum,res)) return true;
// 如果飞过去之后不行(即backtracking()返回false,则回溯选择另一条路
res.pop_back();
target.second++;
}
}
return false;
}
};
class Solution {
private:
vector<vector<string>> res;
void backtracking(int n,int row,vector<string> &chessboard){
if(row==n){
res.push_back(chessboard);
return ;
}
for(int col= 0;col<n;col++){
if(isValid(n,row,col,chessboard)){//如果此处可以放置Q
chessboard[row][col]='Q';
backtracking(n,row+1,chessboard);
chessboard[row][col]='.';
}
}
}
// 验证该处是否可以放置Q
bool isValid(int n,int row,int col,vector<string> &chessboard){
// 验证列
for(int i=0;i<row;i++){//不用i<n的原因是row后面的行还没有放置,一定不会有Q,所以不用检查
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;
}
public:
vector<vector<string>> solveNQueens(int n) {
std::vector<std::string> chessboard(n,std::string(n,'.'));
backtracking(n,0,chessboard);
return res;
}
};
class Solution {
private:
bool backtracking(vector<vector<char>> &board){
for(int i=0;i<board.size();i++){
for(int j=0;j<board[0].size();j++){
if(board[i][j]=='.'){//如果board[i][j]为空,考虑填空
for(char k='1';k<='9';k++){//遍历1-9看看填哪个
if(isValid(i,j,k,board)){//对1-9检查合法性
board[i][j]=k;
if(backtracking(board)) return true;
board[i][j]='.';
}
}
//1-9都遍历完了没return true就return false
return false;
}
}
}
// 遍历完没有return false说明找到合适的数独了
return true;
}
// 判断board[row][col]能否填val
bool isValid(int row,int col,char val,vector<vector<char>> &board){
// 检查行
for(int j=0;j<9;j++){
if(board[row][j]==val){
return false;
}
}
// 检查列
for(int i=0;i<9;i++){
if(board[i][col]==val){
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]==val){
return false;
}
}
}
return true;
}
public:
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};