-
今日学习的文章链接,或者视频链接
-
自己看到题目的第一想法
-
看完代码随想录之后的想法
332
class Solution {
public:
// 邻接表形式的图,key 是机场名字,value 是从该机场出发能够到达的机场列表
unordered_map<string, vector<string>> graph;
// 和 graph 对应,记录每张机票是否被使用过
// 比如 graph["JFK"][2] = true 说明从机场 JFK 出发的第 3 张机票已经用过了
unordered_map<string, vector<bool>> used;
vector<vector<string>> tickets;
// 回溯算法使用的数据结构
deque<string> track;
// 回溯算法记录结果
vector<string> res;
void backtrack(string airport) {
if (!res.empty()) {
// 已经找到答案了,不用再计算了
return;
}
if (track.size() == tickets.size() + 1) {
// track 里面包含了所有的机票,即得到了一个合法的结果
// 注意 tickets.size() 要加一,因为 track 里面额外包含了起点 "JFK"
res = vector<string>(track.begin(), track.end());
return;
}
if (!graph.count(airport)) {
// 没有从 s 出发的边
return;
}
// 遍历当前机场所有能够到达的机场
vector<string>& nextAirports = graph[airport];
for (int i = 0; i < nextAirports.size(); i++) {
string& nextAirport = nextAirports[i];
if (used[airport][i]) {
// 如果这张机票被使用过,跳过
continue;
}
// 做选择
used[airport][i] = true;
track.push_back(nextAirport);
// 递归
backtrack(nextAirport);
// 撤销选择
used[airport][i] = false;
track.pop_back();
}
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
this->tickets = tickets;
// 1. 用机场的名字构建邻接表
for (vector<string>& ticket : tickets) {
string from = ticket[0];
string to = ticket[1];
if (!graph.count(from)) {
graph[from] = vector<string>();
}
graph[from].push_back(to);
}
// 2. 对邻接表的每一行进行排序,保证字典序最小
for (auto& p : graph) {
sort(p.second.begin(), p.second.end());
}
// 3. 初始化 used 结构,初始值都为 false
for (auto& p : graph) {
used[p.first] = vector<bool>(p.second.size(), false);
}
// 4. 从起点 "JFK" 开始启动 DFS 算法递归遍历
track.push_back("JFK");
backtrack("JFK");
return res;
}
};
51
class Solution {
public:
vector<vector<string>> result;
void backtracking(int n, int row, vector<string>& chessboard)
{
if (row == n){
result.push_back(chessboard);
}
for(int i = 0;i<n;i++){
if (isValid(row,i,chessboard,n))
{
chessboard[row][i] = 'Q';
backtracking(n,row+1,chessboard);
chessboard[row][i]='.';
}
}
}
bool isValid(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) {
vector<string> chessboard(n, string(n, '.'));
backtracking(n,0,chessboard);
return result;
}
};
37:
class Solution {
public:
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]=='.'){
for(char k = '1';k<='9';k++){
if(isValid(i,j,k,board)){
board[i][j]=k;
bool result = backtracking(board);
if(result == true) return true;
board[i][j] = '.';
}
}
return false;
}
}
}
return true;
}
bool isValid(int row, int col, char val, vector<vector<char>>& board) {
for (int i = 0; i < 9; i++) { // 判断行里是否重复
if (board[row][i] == val) {
return false;
}
}
for (int j = 0; j < 9; j++) { // 判断列里是否重复
if (board[j][col] == val) {
return false;
}
}
int startRow = (row / 3) * 3;
int startCol = (col / 3) * 3;
for (int i = startRow; i < startRow + 3; i++) { // 判断9方格里是否重复
for (int j = startCol; j < startCol + 3; j++) {
if (board[i][j] == val ) {
return false;
}
}
}
return true;
}
void solveSudoku(vector<vector<char>>& board) {
backtracking(board);
}
};
-
自己实现过程中遇到哪些困难
-
今日收获,记录一下自己的学习时长