7.13N皇后(LC51-H)
2024-01-02 14:05:55
算法:
N皇后是回溯的经典题
画树:
假设N=3
皇后们的约束条件:
- 不能同行
- 不能同列
- 不能同斜线
回溯三部曲:
1.确定函数参数和返回值
返回值:void
参数:
int n:题目给出,N皇后的个数,棋盘大小nxn
int row:用row来记录当前遍历到棋盘的第几层了
char[][] chessboard:二维字符数组,
表示棋盘。每个`chessboard[i]
`?都是一个字符数组,而`chessboard[i][j]
`?则表示二维数组中特定位置?`(i, j)
`?处的字符值。
2.确定终止条件
row==n
当递归到棋盘最底层(也就是叶子节点)的时候,就可以收集结果并返回了。
3.单层递归逻辑(for循环)
每次都是要从新的一行的起始位置开始搜,所以都是从0开始。
for (int col = 0;col < n; col++) {
if (isValid (row, col, n, chessboard)) {
// 验证合法就可以放
chessboard[row][col] = 'Q';
//递归
backTrack(n, row+1, chessboard);
//回溯,撤销皇后
chessboard[row][col] = '.';
}
}
验证棋盘是否合法
isValid:先判错
按照如下标准去重:
- 不能同行
- 不能同列
- 不能同斜线 (45度和135度角)
同列
for (int i = 0; i < row; i++) { // 这是一个剪枝
if (chessboard[i][col] == 'Q') {
return false;
}
}
同行(其实可以不放,因为在单层搜索的过程中,每一层递归,只会选for循环(也就是同一行)里的一个元素,所以不用去重了。)
for (int j = 0; i < col; j++) { // 这是一个剪枝
if (chessboard[row][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;
}
}
正确代码:
class Solution {
List<List<String>> result = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] chessboard2 = new char[n][n];
for (char[] c:chessboard2){
Arrays.fill(c,'.');
}
backtracking(n, 0, chessboard2);
return result;
}
void backtracking (int n, int row, char[][] chessboard){
if (row == n) {
result.add (Array2List(chessboard));
return;
}
for (int col=0; col<n; col++){
if (isValid(col, row, n, chessboard)) {
chessboard[row][col] = 'Q';
backtracking(n, row+1, chessboard);
chessboard[row][col] = '.';
}
}
}
boolean isValid(int col, int row, int n, char[][] chessboard){
//同列
for (int i=0; i<row; i++){
if (chessboard[i][col] == 'Q') return false;
}
//同行
for (int i=0; i<col; i++){
if (chessboard[row][i] == '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;
}
List Array2List(char[][] chessboard) {
List<String> list = new ArrayList<>();
for (char[] c : chessboard) {
list.add(String.copyValueOf(c));
}
return list;
}
}
注意:
(1)想要将二维字符数组转换为 List<List<String>> 的格式。需要编写一个方法(Array2List)来实现这一转换。
(2)在 Java 中,字符的比较应该使用单引号而不是双引号。因此,应该使用单引号`'Q'
`和`'.'
`来比较而不是`"Q"
`和`"."
`。
时间空间复杂度:
文章来源:https://blog.csdn.net/m0_50696252/article/details/135332415
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!