Day30 | 332.重新安排行程, 51. N皇后, 37. 解数独
重新安排行程
LeetCode题目:https://leetcode.cn/problems/reconstruct-itinerary/
整体思路
本题主要要把握的点是对图的构建和计数。由于需要存放from和to两个地址,还要进行路径的计数。因此使用 u n o r d e r e d unordered unordered_ m a p < s t r i n g , m a p < s t r i n g , i n t > > map<string,map<string,int>> map<string,map<string,int>>来进行存储。from来确定对to和次数的索引。
此外,搜索也可以使用特有的搜索方法,但要注意map的key索引是不允许修改的,如果引用方法获取,需要加const。
代码如下:
class Solution {
public:
unordered_map<string,map<string,int>> targets;
bool backTrack(int ticketsum,vector<string>& result){
if(result.size()==ticketsum+1){
return true;
}
for(pair<const string,int>& target:targets[result[result.size()-1]]){
if(target.second>0){
result.push_back(target.first);
target.second--;
if(backTrack(ticketsum,result)) return true;
result.pop_back();
target.second++;
}
}
return false;
}
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> result;
result.clear();
for(const vector<string>& vec:tickets){
targets[vec[0]][vec[1]]++;
}
result.push_back("JFK");
backTrack(tickets.size(),result);
return result;
}
};
N皇后
LeetCode题目:https://leetcode.cn/problems/n-queens/
解题思路
N皇后问题,关键点在于对二维组的添加元素如何操作。以及isValid方法的构造。 v e c t o r < s t r i n g > vector<string> vector<string>可以把每个string看做行,然后进行对每行内部的操作。为了修改方便使用vector数组。
其他倒是没什么坑,代码如下:
class Solution {
private:
vector<vector<string>> result;
bool isValid(int n,int r, int l,vector<string>& chessboard){
for(int i=0;i<n;i++){
if(chessboard[i][l]=='Q'||chessboard[r][i]=='Q') return false;
if((r+i)<n&&(l+i)<n) {
if(chessboard[r+i][l+i]=='Q') return false;
}
if((r-i)>=0&&(l-i)>=0){
if(chessboard[r-i][l-i]=='Q') return false;
}
if((r+i)<n&&(l-i)>=0){
if(chessboard[r+i][l-i]=='Q') return false;
}
if((r-i)>=0&&(l+i)<n){
if(chessboard[r-i][l+i]=='Q') return false;
}
}
return true;
}
void backTracking(int n, int row,vector<string>& chessboard){
if(row==n){
result.push_back(chessboard);
return ;
}
for(int l = 0;l<n;l++){
if(isValid(n,row,l,chessboard)){
chessboard[row][l] = 'Q';
backTracking(n,row+1,chessboard);
chessboard[row][l] = '.';
}
}
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<string> chessboard(n, string(n, '.'));
backTracking(n,0,chessboard);
return result;
}
};
解数独
LeetCode题目:https://leetcode.cn/problems/sudoku-solver/
解题思路
解决数独问题乍一看与N皇后没有差别,因为同样是对二维进行操作,注意isValid内部的操作。但应当注意的是,N皇后可以看做是二维的特殊情况,由于每行不允许有多个皇后,所以每一行在添加一个皇后都可以直接向下一行搜索。
但是数独问题中每一行的空白是未知的,因此需要在递归函数内部进行循环,然后当该行迭代结束后再换到下一行。所以属于是二维的递归问题。
代码如下:
class Solution {
private:
bool isValid(int row, int col, vector<vector<char>>& board){
for(int i=0;i<9;i++){
if(i!=row&&board[i][col]==board[row][col]) return false;
if(i!=col&&board[row][i]==board[row][col]) return false;
}
int rowStep = 3*(row/3);
int colStep = 3*(col/3);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if((i+rowStep)==row&&(j+colStep)==col) continue;
if(board[i+rowStep][j+colStep]==board[row][col]) return false;
}
}
return true;
}
bool backTracking(vector<vector<char>>& board,int rowtIndex){
for(int i=rowtIndex;i<9;i++){
for(int j= 0;j<9;j++){
if(board[i][j]!='.') continue;
for(int k=1;k<=9;k++){
board[i][j]=k+'0';
if(isValid(i,j,board)){
if(backTracking(board,i)) return true;
}
board[i][j] = '.';
}
return false;
}
}
return true;
}
public:
void solveSudoku(vector<vector<char>>& board) {
backTracking(board,0);
return ;
}
};