N皇后問題

 

題目描述:

LeetCode題目51. N皇后
n 皇后問題研究的是如何將 n 個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊。

上圖爲 8 皇后問題的一種解法。

給定一個整數 n,返回所有不同的 n 皇后問題的解決方案。

每一種解法包含一個明確的 n 皇后問題的棋子放置方案,該方案中 ‘Q’ 和 ‘.’ 分別代表了皇后和空位。
 

示例1
輸入: 4
輸出: [
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],

["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解釋: 4 皇后問題存在兩個不同的解法。

思路分析:

約束條件爲每個棋子所在的行、列、對角線都不能有另一個棋子。

使用一維數組表示一種解法,下標(index)表示行,值(value)表示該行的Q(皇后)在哪一列。
每行只存儲一個元素,然後遞歸到下一行,這樣就不用判斷行了,只需要判斷列和對角線。

當result[row] = column時,即row行的棋子在column列。

對於[0, row-1]的任意一行(i 行),若 row 行的棋子和 i 行的棋子在同一列,則有result[i] == column;
若 row 行的棋子和 i 行的棋子在同一對角線,等腰直角三角形兩直角邊相等,即 row - i == Math.abs(result[i] - column)

布爾類型變量 isValid 的作用是剪枝,減少不必要的遞歸。

解法:

import java.util.LinkedList;
import java.util.List;

public class NQueens {

	public static void main(String[] args) {
		NQueens   queen=new NQueens();
		List<List<String>> myList=queen.solveNQueens(4);
        System.out.println(myList);
	}
    public List<List<String>> solveNQueens(int n) {
    	int[] result=new int[n];
    	List<List<String>> resultList=new LinkedList<>();
    	dfs(resultList,result,0,n);
    	return resultList;
    }
    public void dfs(List<List<String>> resultList,int[] result,int row,int n) {
    	//核心函數,回溯法的思想
    	for(int column=0;column<n;column++) {
    		boolean isVaild=true;
    		result[row]=column;
    		//用於判斷皇后當前皇后是否可以放在此位置
    		for(int i=row-1;i>=0;i--) {
    			if(result[i]==column||row-i==Math.abs(result[i]-column)) {
    				isVaild=false;
    				break;
    			}
    		}
    		if(isVaild) {
    			//遞歸終止條件,如果全部擺好,則輸出所有皇后的座標
    			if(row==n-1) {
    				List<String> list=new LinkedList<>();
    				for(int x=0;x<n;x++) {
    					StringBuilder sb=new StringBuilder();
    					for(int y=0;y<n;y++) {
    						sb.append(result[x]==y?"Q":".");
    					}
    					list.add(sb.toString());
    				}
    				resultList.add(list);
    				return;
    				
    			}else {
    			   dfs(resultList,result,row+1,n);
    			}
    			
    		}
    	}
    }
}

運行結果:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章