N皇后问题
Posted leodaxin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了N皇后问题相关的知识,希望对你有一定的参考价值。
/**
* 如何判断是否是对角线,对应坐标相减结果绝对值相等则对角线: Math.abs(x1 - x2) == Math.abs(y1 - y2);
*/
N皇后第一版代码:性能较差,但是完全由自己写粗来的,基于此版本优化:
package com.javartisan.redpacket; import java.util.ArrayList; import java.util.HashSet; import java.util.List; /** * 如何判断是否是对角线,对应坐标相减结果绝对值相等则对角线: Math.abs(x1 - x2) == Math.abs(y1 - y2); */ class Solution public static List<List<String>> solveNQueens(int n) List<List<String>> ans = new ArrayList<>(); byte[][] mtx = new byte[n][n]; ArrayList<String> an = new ArrayList<>(); for (int i = 0; i < n; i++) an.add(""); trace(ans, an, n, n, mtx); HashSet<List<String>> set = new HashSet<>(ans); return new ArrayList<>(set); public static void trace(List<List<String>> ans, ArrayList<String> an, int n, int cur, byte[][] mtx) if (cur == 0) ans.add((List<String>) an.clone()); return; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) if (check(mtx, i, j, n)) mtx[i][j] = 1; StringBuilder sb = new StringBuilder(); for (int k = 0; k < n; k++) if (k == j) sb.append("Q"); else sb.append("."); an.set(i, sb.toString()); trace(ans, an, n, --cur, mtx); an.set(i, ""); mtx[i][j] = 0; cur++; public static boolean check(byte[][] mtx, int x, int y, int n) boolean status = true; for (int i = 0; i < n && status; i++) if (mtx[x][i] == 1) status = false; break; for (int i = 0; i < n && status; i++) if (mtx[i][y] == 1) status = false; break; for (int i = x, j = y; i > 0 && j > 0 && status; i--, j--) if (mtx[i - 1][j - 1] == 1) status = false; break; for (int i = x, j = y; i < n - 1 && j < n - 1 && status; i++, j++) if (mtx[i + 1][j + 1] == 1) status = false; break; for (int i = x, j = y; i < n - 1 && j > 0 && status; i++, j--) if (mtx[i + 1][j - 1] == 1) status = false; break; for (int i = x, j = y; i > 0 && j < n - 1 && status; i--, j++) if (mtx[i - 1][j + 1] == 1) status = false; break; return status; public static void main(String[] args) byte[][] mtx = 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; int n =7; long start = System.currentTimeMillis(); System.out.println(solveNQueens(n)); System.out.println(System.currentTimeMillis() - start); System.out.println(solveNQueens(n).size());
简单优化版:
import java.util.ArrayList; import java.util.HashSet; import java.util.List; /** * 如何判断是否是对角线,对应坐标相减结果绝对值相等则对角线: Math.abs(x1 - x2) == Math.abs(y1 - y2); */ class Solution public static List<List<String>> solveNQueens(int n) byte[] x = new byte[n]; byte[] y = new byte[n]; List<List<String>> ans = new ArrayList<>(); byte[][] mtx = new byte[n][n]; ArrayList<String> an = new ArrayList<>(); for (int i = 0; i < n; i++) an.add(""); trace(ans, an, n, n, mtx, x, y); HashSet<List<String>> set = new HashSet<>(ans); return new ArrayList<>(set); public static void trace(List<List<String>> ans, ArrayList<String> an, int n, int cur, byte[][] mtx, byte[] usedX, byte[] usedY) if (cur == 0) ans.add((List<String>) an.clone()); return; for (int i = 0; i < n; i++) if (usedX[i] == 1) continue; for (int j = 0; j < n; j++) if (usedY[j] != 1 && check(mtx, i, j, n)) mtx[i][j] = 1; usedX[i] = 1; usedY[j] = 1; StringBuilder sb = new StringBuilder(); for (int k = 0; k < n; k++) if (k == j) sb.append("Q"); else sb.append("."); an.set(i, sb.toString()); trace(ans, an, n, --cur, mtx, usedX, usedY); an.set(i, ""); mtx[i][j] = 0; usedX[i] = 0; usedY[j] = 0; cur++; public static boolean check(byte[][] mtx, int x, int y, int n) boolean status = true; for (int i = 0; i < n && status; i++) if (mtx[x][i] == 1) status = false; break; for (int i = 0; i < n && status; i++) if (mtx[i][y] == 1) status = false; break; for (int i = x, j = y; i > 0 && j > 0 && status; i--, j--) if (mtx[i - 1][j - 1] == 1) status = false; break; for (int i = x, j = y; i < n - 1 && j < n - 1 && status; i++, j++) if (mtx[i + 1][j + 1] == 1) status = false; break; for (int i = x, j = y; i < n - 1 && j > 0 && status; i++, j--) if (mtx[i + 1][j - 1] == 1) status = false; break; for (int i = x, j = y; i > 0 && j < n - 1 && status; i--, j++) if (mtx[i - 1][j + 1] == 1) status = false; break; return status; public static void main(String[] args) byte[][] mtx = 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ; System.out.println(solveNQueens(4).size()); int n = 7; long start = System.currentTimeMillis(); System.out.println(solveNQueens(n)); System.out.println(System.currentTimeMillis() - start); start = System.currentTimeMillis(); System.out.println(solveNQueens(8).size()); System.out.println(System.currentTimeMillis() - start);
以上是关于N皇后问题的主要内容,如果未能解决你的问题,请参考以下文章