leetCode 51.N-Queens (n皇後問題) 解題思路和方法
阿新 • • 發佈:2017-06-23
dex 數據 我想 attack upload sar alt row queen
N-Queens
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens‘ placement, where ‘Q‘ and ‘.‘ both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens‘ placement, where ‘Q‘ and ‘.‘ both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
思路:本題大的方法上我想到了兩個思路,第一個是將n皇後問題轉化為全排列問題。
設x[n]為一組解。代表第i行第x[i]列放置了皇後。
所以求出全排列,然後推斷是否合法就可以。
代碼例如以下(沒有Ac,進一步優化之後應該是能夠Ac的):
public class Solution { public List<List<String>> solveNQueens(int n) { List<List<String>> returnList = new ArrayList<List<String>>(); /** * x[i]為第i列存放的位置 * 轉化為0-(n-1)的全排列,然後推斷全排列的位置是否合法就可以 */ int[] num = new int[n]; int i = 0; while(i < n){ num[i] = i;//填充數組為0-(n-1) i++; } List<List<Integer>> list = permuteUnique(num); for(List<Integer> al : list){//對每一組數據處理 for(i = 0; i < al.size(); i++){ if(!check(al, i, al.get(i))) break;//不合法跳出 } if(i == n){//到最後一位,說明所有合法 List<String> ls = new ArrayList<String>(); for(i = 0; i < al.size(); i++){ String s = "";//每一組的String for(int j = 0; j < n;j++){ if(j == al.get(i)){ s += "Q";//放置皇後的位置 } else{ s += ".";//不放的位置 } } ls.add(s);//加入到ls } returnList.add(ls);//加入一組解 } } return returnList; } /** * 推斷是否合法 * @param al 一組解 * @param i 當前行 * @param x 當前列 * @return 是否合法 */ boolean check(List<Integer> al,int i,int x){ for(int k = 0; k < i; k++){//僅僅與上方比較,不然與會自身比較 if(al.get(k) == x || x - i == al.get(k) - k || x + i == al.get(k) + k) return false; } return true; } //求全排列 public static List<List<Integer>> permuteUnique(int[] num) { List<List<Integer>> returnList = new ArrayList<List<Integer>>(); returnList.add(new ArrayList<Integer>()); for (int i = 0; i < num.length; i++) { Set<List<Integer>> currentSet = new HashSet<List<Integer>>(); for (List<Integer> l : returnList) { for (int j = 0; j < l.size() + 1; j++) { l.add(j, num[i]); List<Integer> T = new ArrayList<Integer>(l); l.remove(j); currentSet.add(T); } } returnList = new ArrayList<List<Integer>>(currentSet); } return returnList; } }
還有一種思路是回溯法,符合要求的往下走。不符合要求的往回退。
詳細代碼:
public class Solution { /** * 這題的總體思想是建一個x[n]的數組,意為第i放第x[i]列放置皇後 * 皇後的合法推斷規則是列不相等,斜線上也不相等 * i + x[i] == j + x[j] 表示正斜線一致 * x[i] - i = x[j] - j 表示負斜線上一致 都不合法 */ List<List<String>> list;//保存結果 public List<List<String>> solveNQueens(int n) { list = new ArrayList<List<String>>(); int[] x = new int[n];//保存結果 queens(x, n, 0); return list; } void queens(int[] x,int n,int row){ for(int i = 0; i < n; i++){ if(check(x,n,row,i)){//推斷合法 x[row] = i;//將皇後放在第row行,第i列 if(row == n-1){//假設是最後一行,則輸出結果 addList(x,n); x[row] = 0;//回溯,尋找下一個結果 return; } queens(x, n, row+1);//尋找下一行 x[row] = 0;//回溯 } } } /** * 將每一組的結果加入list * @param x 數組解 * @param n 棋盤長寬 */ private void addList(int[] x,int n) { //加入結果 String[][] sArr = new String[n][n]; List<String> al = new ArrayList<String>(); for(int i = 0; i < n ; i++){ Arrays.fill(sArr[i], ".");//先填充. sArr[i][x[i]] = "Q";//特定位置放置Q String s = ""; for(String str:sArr[i]){ s += str;//加在一起 } al.add(s);//加入一行 } list.add(al);//加入一組解 } /** * @param x 數組解 * @param n 棋盤長寬 * @param index 當前放置行 * @param i 當前放置列 * @return */ boolean check(int[] x,int n,int row, int col){ for(int i = 0; i < row; i++){ //由於行不相等,推斷列是否相等。斜線上是否相等 if(x[i] == col || x[i] + i == col + row || x[i] - i == col - row) return false; } return true; } }
leetCode 51.N-Queens (n皇後問題) 解題思路和方法