代码随想录算法训练营第二十五天| 332.重新安排行程(可跳过) 51. N皇后(可跳过) 37. 解数独(可跳过)

 332.重新安排行程(可跳过)

难点:

1,解决死锁问题,我采用的是 selected,但是不会出现A->B->A这条信息

2,即使出现A-》B-》A,因为是有多条路径,所以无法找到合适的含有全部机场的路径

3,保证顺序

代码:

 1 //机票信息 -》 一条遍历所有机场的路径
 2 //步骤:
 3 // 1,根据 start 压进去它的所有目的地信息
 4 // 2, 目的地作为起始节点,进行遍历
 5 // 3,如果这条路径到最后也没有遍历所有,那么就回复原装,开始遍历下一条路径
 6 bool findItinerary_trackBack(map<string,map<string,int>>&tickets,int ticketNum, string start, vector<string>&result)
 7 {
 8     if (result.size() == ticketNum +1)
 9     {
10         return true;
11     }
12 
13     for (pair<const string,int>& ticket : tickets[start])
14     {
15         if (ticket.second > 0)
16         {
17             result.push_back(ticket.first);
18             ticket.second--;
19             bool isComplete = findItinerary_trackBack(tickets, ticketNum, ticket.first, result);
20             if (isComplete) return true;
21             ticket.second++;
22             result.pop_back();
23         }
24 
25     }
26     return false;
27 }
28 
29 vector<string> findItinerary(vector<vector<string>>& tickets) {
30     //需要tickets,转换成map《start,map》
31     map<string, map<string, int>> tickets_map;
32     for (auto ticket : tickets)
33     {
34         
35         tickets_map[ticket[0]][ticket[1]]++;
36     }
37 
38     vector<string>result;
39     result.push_back("JFK");
40     findItinerary_trackBack(tickets_map, tickets.size(), "JFK", result);
41     return result;
42 }

 51. N皇后(可跳过)

难点:

1,判断是否可用

注意:

1,因为一行只能添加一个皇后,所以可以按照行进行遍历

2,只处理完当前行,就不处理了

代码:

 1 bool IsQueenValid(const vector<string>&path, int curRow,int curCol)
 2 {
 3     if (path.size() == 0)
 4         return true;
 5 
 6     //判断 col row--没有
 7     for (int i = curRow-1; i >= 0; i--)
 8     {
 9         if (path[i][curCol] == 'Q')
10         {
11             return false;
12         }
13     }
14 
15     //左斜向上没有Q
16     for (int i = curRow-1, j = curCol-1; i >= 0&& j >= 0; i--, j--)
17     {
18         if (path[i][j] == 'Q')
19             return false;
20     }
21 
22     //右斜向上没有Q
23     for (int i = curRow-1, j = curCol+1; i >=0 && j < path[0].size(); i--,j++)
24     {
25         if (path[i][j] == 'Q')
26             return false;
27     }
28 
29     return true;
30 }
31 
32 void solveNQueen_trackBack(const vector<string>& nums,vector<string>&path, int curRow, vector<vector<string>>& result)
33 {
34     if (curRow == nums.size())
35     {
36         result.push_back(path);
37         return;
38     }
39 
40     //对于每一行,先判断,我把节点放到这里行不行,如果不行continue
41     for (int i = 0; i < nums[curRow].size(); i++)
42     {
43         if (IsQueenValid(path, curRow, i))
44         {
45             string cur_ = nums[curRow];
46             cur_[i] = 'Q';
47             path.push_back(cur_);
48             solveNQueen_trackBack(nums, path, curRow + 1, result);
49             path.pop_back();
50         }
51     }
52 }
53 vector<vector<string>> solveNQueens(int n) {
54     vector<vector<string>> result;
55     vector<string>path;
56     vector<string> nums(n,string(n,'.'));
57     solveNQueen_trackBack(nums, path, 0, result);
58     return result;
59 }

 37. 解数独(可跳过) 

注意:

需要让每一行都填满,而不能填了一个数字就到下一行,这样的话会一直填不满

思路:

对每一个都进行排序,然后在判断所有的节点,因为有当前节点是否是.的判断,所以直接迭代是没有问题的

代码:

 1 bool isValid_sudoku(vector<vector<char>>& board,int row, int col, char val)
 2 {
 3     for (int i = 0; i < 9; i++) { // 判断行里是否重复
 4         if (board[row][i] == val) {
 5             return false;
 6         }
 7     }
 8     for (int j = 0; j < 9; j++) { // 判断列里是否重复
 9         if (board[j][col] == val) {
10             return false;
11         }
12     }
13     int startRow = (row / 3) * 3;
14     int startCol = (col / 3) * 3;
15     for (int i = startRow; i < startRow + 3; i++) { // 判断9方格里是否重复
16         for (int j = startCol; j < startCol + 3; j++) {
17             if (board[i][j] == val) {
18                 return false;
19             }
20         }
21     }
22     return true;
23 }
24 
25 //需要保证,每一层都填满了
26 // false: 就是这一层 还没填完,就到下一层了,这是不可以的
27 bool solveSudoku_trackBack(vector<vector<char>>& board)
28 {
29     for (int curRow = 0; curRow < board.size(); curRow++)
30     {
31         for (int i = 0; i < board[0].size(); i++)
32         {
33             if (board[curRow][i] == '.')
34             {
35                 for (char num = '1'; num <= '9'; num++)
36                 {
37                     if (isValid_sudoku(board, curRow, i, num))
38                     {
39                         board[curRow][i] = num;
40                         bool isComplete = solveSudoku_trackBack(board);
41                         if (isComplete) return true;
42                         board[curRow][i] = '.';
43                     }
44                 }
45                 return false;
46             }
47         }
48 
49     }
50 
51     return true;
52 }
53 
54 //难点
55 //怎么去回溯,什么时候设置终止条件
56 void solveSudoku(vector<vector<char>>& board) {
57     solveSudoku_trackBack(board);
58 }

 

posted @ 2023-07-06 11:27  博二爷  阅读(6)  评论(0编辑  收藏  举报