Files
leetcode/51.n-queens.java
2025-05-17 17:06:34 +08:00

184 lines
4.7 KiB
Java

/*
* @lc app=leetcode id=51 lang=java
*
* [51] N-Queens
*/
// @lc code=start
import java.util.ArrayList;
class Solution {
public List<List<String>> solveNQueens(int n) {
int[][] m = createMap(n);
List<List<String>> r = new ArrayList<>();
dfsNQueen(r, m, 0, n, 0);
return r;
}
private void dfsNQueen(List<List<String>> r, int[][] m, int i, int n, int p) {
if(i == n && pass(m, n, i)) {
r.add(buildRetStr(m));
return;
} else if (i>=n) {
return;
}
if(!pass(m,n, i)) {
return;
}
for(int j = p; j<n*n; j++) {
int x = j / n;
int y = j % n;
if(m[x][y] == 0) {
m[x][y] = 1;
dfsNQueen(r, m, i+1, n, j+1);
m[x][y] = 0;
}
}
}
private boolean pass(int[][] m , int n, int i) {
// todo: check logic
return checkRow(m, n, i) && checkColumn(m, n) && checkLeftSlash(m,n) && checkRightSlash(m,n);
}
private boolean checkRow(int[][] m, int n, int s) {
for(int i=0; i<n; i++) {
if(!checkWithStrategy(m, new Point(i, 0), n, pos->{
return new Point(pos.x, pos.y+1);
})) {
return false;
}
if(i < s && !checkRowNotEmpty(m, n, i)) {
return false;
}
}
return true;
}
private boolean checkRowNotEmpty(int[][] m, int n, int s) {
for(int i=0; i<n; i++) {
if(m[s][i] != 0) {
return true;
}
}
return false;
}
private boolean checkColumn(int[][] m, int n) {
for(int i = 0; i<n; i++) {
if(!checkWithStrategy(m, new Point(0, i), n, pos->{
return new Point(pos.x+1, pos.y);
})) {
return false;
}
}
return true;
}
private boolean checkLeftSlash(int[][] m, int n) {
for(int i = 0; i<n; i++) {
if(!checkWithStrategy(m, new Point(i, 0), n, pos->{
return new Point(pos.x+1, pos.y+1);
})) {
return false;
}
if(!checkWithStrategy(m, new Point(0, i), n, pos->{
return new Point(pos.x+1, pos.y+1);
})) {
return false;
}
}
return true;
}
private boolean checkRightSlash(int[][] m, int n) {
for(int i = 0; i<n; i++) {
if(!checkWithStrategy(m, new Point(0, i), n, pos->{
return new Point(pos.x+1, pos.y-1);
})) {
return false;
}
if(!checkWithStrategy(m, new Point(i, n-1), n, pos->{
return new Point(pos.x+1, pos.y-1);
})) {
return false;
}
}
return true;
}
private boolean checkWithStrategy(int[][] m, Point pos, int n,Function<Point, Point> incrStrategy) {
int c = 0;
if(m[pos.x][pos.y] !=0) {
c++;
}
for(int i=0;i<n-1;i++) {
pos = incrStrategy.apply(pos);
if(pos.x >=n || pos.y>= n || pos.x <0 || pos.y <0) {
break;
}
if(m[pos.x][pos.y] != 0) {
c++;
if(c>1) {
return false;
}
}
}
return true;
}
private int[][] createMap(int n) {
int[][] r = new int[n][n];
zset(r);
return r;
}
private void zset(int[][] m) {
if(m == null) {
return;
}
for (int i = 0; i < m.length; i++) {
if(m[i]==null) {
continue;
}
for(int j = 0; j < m[i].length; j++) {
m[i][j] = 0;
}
}
}
private List<String> buildRetStr(int[][] m) {
List<String> r = new ArrayList<String>();
if(m == null) {
return r;
}
for(int i = 0; i<m.length; i++) {
int[] t = m[i];
if(t == null) {
r.add("");
continue;
}
StringBuilder sbd = new StringBuilder();
for(int j = 0; j<t.length; j++) {
sbd.append(t[j]==0?".":"Q");
}
r.add(sbd.toString());
}
return r;
}
public static class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
}
// @lc code=end