总结:代码随想录
51. N 皇后
1.思路
和那个号码一样都是一个二维数组的问题,但是这个题目有条件,遍历每一行,看每一行能不能放入‘Q’,只遍历到了末尾就是正确的结果,就可以加入结果集中
2.回溯法
class Solution {
public:
vector<vector<string>>result;
void backtracking(int n, vector<string>& chessboard, int row) {
if (row == n) {
result.push_back(chessboard);
return;
}
for (int i = 0; i < n; i++) {
if (isvaild(n, row, i, chessboard)) {
chessboard[row][i] = 'Q';
backtracking(n, chessboard, row + 1);
chessboard[row][i] = '.';
}
}
}
bool isvaild(int n, int row,int col, vector<string>& chessboard) {
//在每一行有没有为q的
for (int i = 0 ,j = col; i < row; i++) {
if (chessboard[i][j] == 'Q') return false;
}
for (int i = row - 1, j = col - 1; i >= 0&& j >= 0; i--, j--) {
if (chessboard[i][j] == 'Q') return false;
}
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) {
std::vector<std::string> chessboard(n, std::string(n, '.'));
backtracking(n, chessboard, 0);
return result;
}
};
3.回溯三部曲
1.确定递归参数类型
除了需要题目给出的参数,还需要给出一个二维数组代表地图,同样知道每一层遍历到哪一行,因为是多行数组,需要知道每次遍历到了哪个数组,需要加入该数组的那个元素,虽然这里的数组都是一样的,所以需要知道每一样就可以了,所以还要一个参数row
2.确定终止条件
当遍历到末尾时,加入最后一个元素,row == n - 1,但是还需要再进行一轮递归,所以return的时候n == row说明就是正确答案
3.确定单层搜索的逻辑
for循环从第一个数开始,不断变更每一样符合条件的点,再树枝遍历到下一行,还没到末尾,继续遍历,直到搜索到了结果,返回上一层,回溯进行树层遍历,反反复复遍历完所有路径,结果集就确定了
4.isvaild条件函数的确定
不能有Q的情况
1.行
2.列
3.45度斜线
4.135度斜线
代码解析
bool isvaild(int n, int row,int col, vector<string>& chessboard) {
//在每一行有没有为q的
for (int i = 0 ,j = col; i < row; i++) {
if (chessboard[i][j] == '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;
}
- 只需要判断前面放过q的行列就行了,其余部分我们都没遍历到,就不需要考虑
1.因为我们都是一行一行遍历,前面的几列肯定都没有,所以这一行的每一列不需要遍历
2.其余部分只需要遍历前面的部分就可以了