Money is not everything. There's MasterCard.
金錢不是萬能的, 有時還須要信用卡。
大話西遊之月光寶盒這部電影已經刷了N遍了。每一次看都有每一次的感悟。若是時光能夠到倒流,我當初就不該該。。。 悔不當初,悔不當初。git
雖然世界上沒有後悔藥,可是算法界倒是有後悔藥的,呢就是---回溯算法。人生不能時光倒流,呢我讓個人算法時光倒流。github
八皇后問題最先是由國際象棋棋手馬克斯·貝瑟爾於1848年提出的,如今都21世紀了,八皇后怎麼能知足我,我決定實現一個N皇后,我想要幾個皇后就要幾個皇后。
算法
全部源碼均已上傳至github:連接數組
家家有本難唸的經,一個皇后已經了不起了。這N皇后嘛,可得好好處理,不能讓她們打架。能夠先聲明一個大小爲N的一維數組,來存儲個人這N位皇后。而後分紅N個階段。bash
大概思路就是這樣。測試
/**
* 皇后數組
*/
private int[] queens;
/**
* n皇后
*/
private int n;
/**
* 擺法數量
*/
private int count;
/**
* 基於8皇后而衍生的N皇后
*
* @param n 皇后的數量
*/
private SolveNQueens(int n) {
queens = new int[n];
this.n = n;
count = 0;
}複製代碼
雖然代碼很精簡,可是關鍵就在於這個遞歸很差理解。循環裏套遞歸,很巧妙。須要一步一步跟一下就知道了。ui
一維數組存儲的值是皇后的位置(0,n-1)。this
默認是要從頭開始的,須要這麼調用該方法calNQueens(0)spa
private void calNQueens(int row) {
if (row == n) {
printQueens(queens);
return;
}
for (int col = 0; col < n; col++) {
if (isSatisfy(row, col)) {
queens[row] = col;
calNQueens(row + 1);
}
}
}複製代碼
該方法須要判斷本身的橫豎排,左右對角線是否有皇后。code
這裏爲了便於理解,因此循環裏放着三個if。
private boolean isSatisfy(int row, int col) {
// System.out.println("(" + row + "," + col + ")");
int leftUp = col - 1;
int rightUp = col + 1;
for (int i = row - 1; i >= 0; --i) {
if (queens[i] == col) return false;
if (leftUp >= 0 && queens[i] == leftUp) return false;
if (rightUp < n && queens[i] == rightUp) return false;
--leftUp;
++rightUp;
}
return true;
}複製代碼
private void printQueens(int[] queens) {
for (int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
if (queens[row] == col) System.out.print("1 ");
else System.out.print("0 ");
}
System.out.println();
}
System.out.println();
++count;
}複製代碼
public static void main(String[] args) {
int n = 8;
SolveNQueens solveNQueens = new SolveNQueens(n);
solveNQueens.calNQueens(0);
System.out.println("共計" + solveNQueens.count + "種擺法.");
}複製代碼
4皇后
八皇后(這裏是包含了旋轉和對稱的解的解,不然是12種擺法)
您的點贊和關注是對我最大的支持,謝謝!