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);
    			}
    			
    		}
    	}
    }
}

运行结果:

 

 

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