[Leetcode]N-Queens
来源:互联网 发布:首轮融资知乎 编辑:程序博客网 时间:2024/06/08 14:22
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.."]]
首先要科普下在西洋棋中queen的角色。对于小时候玩过西洋棋后来就忘光的我来说,看到题目我真的不明白什么叫Queen attack each other。
Queen这个棋子只能竖着来,或者横着来,或者斜着来。基本可以把它理解为愣头青。所以要保证没有任何两个Queen相互攻击,就需要同时满足任意一行或一列不能出现两个Queen,任意一条斜线上也不能出现两个Queen。因此,考虑最基本的方法就是去遍历这个n*n的棋盘,看看如何摆放这n个Queen可以满足要求。
那么如何去遍历呢,想到一种直观的方法。用一个长为n整数数组int[] loc表示棋盘上Queen的位置。具体来说,res的每个元素的index表示表示所处的行,而该index中的值表示改行Queen所在的位置。例如loc[0] = 5表示第0行Queen在第5列。这样的数据结构可以保证任何一行只有一个Queen,因此我们只需要再保证这个Queen所在列和斜线上没有其他Queen,就能说明这个Queen是合法的。利用深度优先算法,不断深入遍历每一行,即,如果当前行中Queen所处位置合法,就递归的遍历下一行,检查是否合法。若所有行均合法,则返回。算法伪代码如下:
main_function(n) :
初始化loc[n]
初始化结果集res
dfs(res, loc, 0, n)
return res
dfs(res,loc,row,n)
if row == n:
return
else
for i in n:
loc[row] = i
if loc[row]合法:
dfs(res,loc,row+1,n)
根据以上伪代码,Java代码实现如下:
public class Solution { public List<String[]> solveNQueens(int n) { ArrayList<String[]> res = new ArrayList<String[]>(); int[] loc = new int[n];//loc表示皇后所在位置,其每一个元素代表一行。比如loc = {1,3,2,0}表示在第一行,皇后在第一列,在第二行,皇后在第3列,以此类推。 dfs(res, loc, 0, n);//从第0行开始深度优先搜索 return res; } private void dfs(ArrayList<String[]> res, int[] loc, int row, int n) { if (row == n) { //如果行数超过n了,说明所有行上的皇后都满足要求,因此用printBoard方法将得到的一种解决方案加入解集res当中 printBoard(res, loc, n); } else { for (int col = 0; col < n; col++) { //遍历每一行中的每一列 loc[row] = col; if (isValid(loc, row)) { //如果改行中皇后处于的位置是合法的,则深度优先搜索下一行row+1 dfs(res, loc, row + 1, n); } } } } private boolean isValid(int[] loc, int row) { for (int i = 0; i < row; i++) { if (loc[row] == loc[i] || Math.abs(loc[row] - loc[i]) == (row - i)) { //到当前行row之前的所有行,判断是否有某行的皇后与当前行皇后处于同一列,若有,返回false不合法 //到当前行row之前的所有行,判断是否有某行的皇后与当前行皇后处于斜线上(等腰三角形),若有,返回false不合法 return false; } } return true; } private void printBoard(ArrayList<String[]> res, int[] loc, int n) { String[] ans = new String[n];//ans的每个元素表示某一种solution中的某一行 for (int i = 0; i < n; i++) { String row = new String(); for (int j = 0; j < n; j++) { if (loc[i] == j) row += "Q"; else row += "."; } ans[i] = row; } res.add(ans); } }
后记补充:后来才发现这就是NP问题。NP问题的一般解决思路就是递归遍历所有可能性,如果当前可能性合法,则递归继续,如果不合法则返回上一级递归。验证当前可能性是否合法需要一个多项式时间的验证程序。所以是NP问题。
- 【LeetCode】N-Queens && N-Queens II
- leetcode N-Queens & N-Queens II
- Leetcode: N-Queens && N-Queens II
- 【Leetcode】【python】N-Queens/N-Queens II
- LeetCode: N-Queens II
- LeetCode: N-Queens
- LeetCode : N-Queens
- LeetCode : N-Queens II
- [Leetcode] N-Queens II
- leetcode 72: N-Queens
- LeetCode 38: N-Queens
- 【leetcode】N-Queens II
- 【leetcode】N-Queens
- LeetCode: N Queens II
- [LeetCode]N-Queens
- [LeetCode]N-Queens II
- [leetcode]N-Queens
- [LeetCode] Anagrams、N-Queens
- centos下两种方法安装git
- 安装谷歌之后如何登陆
- iOS duplicate symbols for architecture i386
- 修改Mac系统JAVA默认设置(10.8以后)
- 二十多高峰会议凸透镜梵蒂冈
- [Leetcode]N-Queens
- findbugs安装
- short-path problem (Floyd)
- HTTP Status 404 - The requested resource (/Test/loginSerlet) is not available.
- 如何防止Session伪造攻击
- rand()函数
- Java之反射、枚举、内省、注解
- 使用hibernate 分表做增删改查
- 类的高级概念(内部类和访问)