51.N皇后
题目解析:这道题是回溯算法中的难题,如果我们按照之前解回溯算法题去树形结构会发现与之前那些收集子集或集合不一样的点在于,我们需要用二维数组去构建一个棋盘,一行一行的去遍历,遍历列的时候就经过递归去遍历。最重要的是去重的过程,要进行列去重,45度去重及135度去重,因为是通过行遍历所以行不用去重。
具体代码如下:
class Solution {
private:
vector<vector<string>> result;
void backTracking(int n,int row,vector<string>& chessbroad){
//n代表棋盘大小,row记录当前遍历到哪一层
if(n == row){
result.push_back(chessbroad);
return;
}
for(int col = 0;col < n;col++){//列控制外层循环,在确定的一行内遍历,由列控制
if(isvalid(row,col,chessbroad,n)){
chessbroad[row][col] = 'Q';//放置皇后
//行控制递归
backTracking(n,row + 1,chessbroad);//从当前行的下一行进行遍历
chessbroad[row][col] = '.';//撤销皇后
}
}
}
bool isvalid(int row,int col,vector<string>& chessbroad,int n){
//列去重
for(int i = 0;i < row;i++){
if(chessbroad[i][col] == 'Q'){
return false;
}
}
//45度去重
for(int i = row - 1,j = col - 1;i >= 0&&j >= 0;i--,j--){
if(chessbroad[i][j] == 'Q'){
return false;
}
}
//135度去重
for(int i = row - 1,j = col + 1;i >= 0&&j < n;i--,j++){
if(chessbroad[i][j] == 'Q'){
return false;
}
}
return true;
}
public:
vector<vector<string>> solveNQueens(int n) {
result.clear();
std::vector<std::string> chessbroad(n,std::string(n,'.'));//大小为n的字符串本身就是一个大小为n的字符数组。
backTracking(n,0,chessbroad);
return result;
}
};
37.解数独
解题思路:
本题与n皇后类似,用递归回溯的方法去匹配看此空填1-9中那个数满足要求。
具体代码如下:
class Solution {
private:
bool backTracking(vector<vector<char>>& board){//因为只要确定最后得出的数独是否满足要求,所以用bool
for(int i = 0;i < board.size();i++){
for(int j = 0;j < board.size();j++){
if(board[i][j] == '.') {
//如果此空为空就看1-9的数字是否能匹配上
for(char k = '1';k <= '9';k++){
if(isVaild(i,j,k,board)){
board[i][j] = k;
bool result = backTracking(board);
if(result) return true;
board[i][j] = '.';
}
}
return false;//如果九个数都不符合就返回false
}
}
}
return true;//遍历完没有返回false,就说明找到了最合适的结果
}
bool isVaild(int row,int col,char val,vector<vector<char>>& board){
//判断行是否有重复
for(int i = 0;i < board.size();i++){
if(board[row][i] == val){
return false;
}
}
//判断列是否有重复
for(int j = 0;j < board.size();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++){
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);
}
};