總體思路:
使用乙個陣列記錄每行放置的皇后的列下標,依次在每一行放置乙個皇后。同時增加約束條件,即新放置的皇后不能和任何乙個已經放置的皇后在同一列以及同一條斜線上,並更新陣列中的當前行的皇后列下標。當找到乙個可能的解之後,將陣列轉換成表示棋盤狀態的列表,並將該棋盤狀態的列表加入返回列表。
因為我們遍歷每一行增加乙個元素,所以保證啦每一行只有乙個元素,我們需要增加三個陣列,columns、diagonals1和 diagonals2,分別表示每一列和兩個斜邊。
時間複雜度:o(n!),其中 n 是皇后數量。
空間複雜度:o(n),其中 n 是皇后數量。空間複雜度主要取決於遞迴呼叫層數、記錄每行放置的皇后的列下標的陣列以及三個集合,遞迴呼叫層數不會超過 n,陣列的長度為n,每個集合的元素個數都不會超過 n。
class solution
public void backtrack(list> solutions, int queens, int n, int row, setcolumns, setdiagonals1, setdiagonals2) else
int diagonal1 = row - i;
if (diagonals1.contains(diagonal1))
int diagonal2 = row + i;
if (diagonals2.contains(diagonal2))
queens[row] = i;
columns.add(i);
diagonals1.add(diagonal1);
diagonals2.add(diagonal2);
backtrack(solutions, queens, n, row + 1, columns, diagonals1, diagonals2);
queens[row] = -1;
columns.remove(i);
diagonals1.remove(diagonal1);
diagonals2.remove(diagonal2);}}
}public listgenerateboard(int queens, int n)
return board;}}
如果利用位運算記錄皇后的資訊,就可以將記錄皇后資訊的空間複雜度從 o(n) 降到 o(1)。
棋盤的每一列對應每個整數的二進位制表示中的乙個數字
從右往左,不能放置皇后的位置標1,可以的位置標0
由此可以得到三個整數的計算方法:
遍歷可以放置皇后的位置時,可以利用以下兩個按位與運算的性質:
class solution
public void solve(list> solutions, int queens, int n, int row, int columns, int diagonals1, int diagonals2) else }}
public listgenerateboard(int queens, int n)
return board;}}
class solution
private void dfs(int row, int col, int pie, int na,int n)
int bit = (~(col | pie | na)) // 獲取當前空位 標識為1
& ((1<0)}}
LeetCode N皇后問題
leetcode上面關於n皇后有兩道題目 51 n queens 52 n queens ii 兩道題目其實差不多,一題是只要返回解的個數就可以了,一題是返回所有的解,做起來一模一樣。什麼是n皇后問題?我們需要在乙個n n的棋盤上,放置n個皇后,使這些皇后不能互相攻擊 即兩個皇后之間不能處於同一行 ...
回溯 n皇后問題
思想 用回溯方法求解,首先要分析問題的求解空間。可用一棵n叉樹表示這個問題的求解空間,在回溯遍歷這個課二叉樹的過程中形成合理的解。對於這棵n叉樹,列序號i 0 n 1 是它的孩子,而每個孩子都有深度為n的子樹 包括自身 這些子樹的層次是n個皇后 也代表每個皇后的行序號,因為不同的皇后肯定不在同一行 ...
回溯 八皇后問題
八皇后問題 國際西洋棋棋手馬克斯 貝瑟爾於1848年提出 在8 8格的西洋棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行 同一列或同一斜線上,問有多少種擺法。分析 八皇后問題是回溯演算法的典型案例。我想我們在自己做的過程中,是這樣的 是先從 0,0 這個座標開始排放皇后,然後 1...