渣渣菜鸡竟然写出了 N皇后
虽然时间和内存都蛮大的 但是 通过了
// leetcode 51
/*
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
*/
思路:从左上角开始 每一列找 每一行找
- 行的增加 可以用index 控制
- 列的增加 即每一行都从0 遍历
- 在其中 如果不符合约束 即行列对角线不满足 即继续
- 如果满足就改变标志位, 继续下一行的遍历 。
- 最终的终止如果满足 就直接return 那么下面的标志位改变也没有用 不走这个
- dfs如果走完了 没有return 就重置标志位 释放该位置。继续下一个位置 即回溯
- 本来初始化了一个棋盘 最后发现没有用。 还是动笔之前要写清楚
import java.util.ArrayList;
import java.util.List;
public class Nqueues {
static List<Integer> temp = new ArrayList<>();
static List<List<String>> rs = new ArrayList<>();
public static List<List<String>> solveNQueens(int n) {
char[][] arr = new char[n][n];
boolean[] isVisitR = new boolean[n];
boolean[] isVisitL = new boolean[n];
//初始化 棋盘
// for(int i = 0; i<n; i++){
// for(int j = 0; j < n; j++){
// arr[i][j] = '.';
// }
// }
dfs(0,0,arr,n,isVisitR,isVisitL);
return rs;
}
public static void dfs(int index,int line,char[][] arr,int n,boolean[] isVisitR, boolean[] isVisitL){
if(index == n && temp.size() == n){
List<String> solve = new ArrayList<>();
int len = temp.size();
for(int i = 0; i< len; i++){
//String s ="";
StringBuilder sb = new StringBuilder();
for(int j = 0; j< n; j++){
//s+=arr[i][j];
if(j == temp.get(i)){
sb.append('Q');
}
else{
sb.append('.');
}
}
// solve.add(s);
solve.add(sb.toString());
}
rs.add(solve);
return;
}
for(int j = 0; j < n; j++){ // && arr[index][j] == '.' 下一行肯定每一个都是.
if(!isVisitR[index] && !isVisitL[j] && isOk(index,j)){
isVisitR[index] = true;
isVisitL[j] = true;
//arr[index][j] = 'Q';
temp.add(j); // 内容放的是第j列 第一个就是第0 行对应的j;
dfs(index+1,j,arr,n,isVisitR,isVisitL);
//arr[index][j] = '.';
isVisitR[index] = false;
isVisitL[j] = false;
temp.remove(temp.size()-1);
}
}
}
// 计算是否在有queue 在一条对角线上
public static boolean isOk(int row, int line){
for(int i = 0; i< row; i++){ // 第 i 列 的皇后 是否冲突 列的绝对值等于行的绝对值
if(Math.abs(row - i) == Math.abs(line - temp.get(i))){
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println(solveNQueens(1));
}
}