N皇后问题
2016-05-17 17:11
211 查看
今天做了leetcode中两道关于N皇后的题目:
51. N-Queens
52. N-Queens II
这是回溯法的经典应用,自己不太会做…主要是研究了下别人的思路,然后自己写了写~
Now, instead outputting board configurations, return the total number of distinct solutions.
(1)简单易懂版本(或者利用循环将其改为非递归形式)
(2)在discuss里看到一种利用位运算降低空间复杂度和时间复杂度的算法,之前也使用过这种手段,即利用每一位(’0’或者’1’)表示一种状态,每次都在更新。
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..”]
]
写完上面那个,下面的就好些一点啦~重点是要选好数据结构去存储solutions。
要学的东西太多了…希望自己每天多打打鸡血,不要像以前那样懒…
51. N-Queens
52. N-Queens II
这是回溯法的经典应用,自己不太会做…主要是研究了下别人的思路,然后自己写了写~
N-Queens II
Follow up for N-Queens problem.Now, instead outputting board configurations, return the total number of distinct solutions.
(1)简单易懂版本(或者利用循环将其改为非递归形式)
public class Solution { int sum = 0; public int totalNQueens(int n) { int[] y = new int ;//解向量,代表皇后被放置在i+1行y[i]+1列(0~n-1/1~n) backtracking(1,n,y); return sum; } private boolean place(int row, int[] y){ //row介于1-n之间,代表目前在讨论第几行的皇后 for(int i=0;i<row-1;i++){ //如果当前的皇后和之前的皇后位于同一列或者对角线(行差等于列差) if(y[i]==y[row-1] || Math.abs(i-row+1)==Math.abs(y[i]-y[row-1])) return false; } return true; } //回溯,需要递归调用 private void backtracking(int row,int n, int[] y){ if(row > n) sum++; else{ //在第row行选择合适的一列把第row个皇后放下 for(int i=0;i<n;i++){ y[row-1] = i; if(place(row,y)) backtracking(row+1,n,y);//位置合适,则开始考虑下一行 } //运行至此,表示没有找到合适的位置,将会返回到上一级的backtracking语句行, //重新摆放上一个皇后,继续寻找可能得解 } } }
(2)在discuss里看到一种利用位运算降低空间复杂度和时间复杂度的算法,之前也使用过这种手段,即利用每一位(’0’或者’1’)表示一种状态,每次都在更新。
public class Solution { int sum = 0; public int totalNQueens(int n) { backtracking(0,n,0,0,0); return sum; } //回溯,需要递归调用 //row: 目前讨论的是在第row行放置queen(row介于0~n-1) //n: 一共需要放置n个queen //以棋盘左下角为原点坐标 //colHasQueen:标记此行之前的哪些column已经放置了皇后, // 如有放置在(r,c)坐标上的皇后则colHasQueen[c]=1; //diagHasQueen:标记此行之前的哪些主对角线已经放置了皇后, // 如有放置在(r,c)坐标上的皇后则diagHasQueen[n-1+r-c]=1;->棋盘格子向对角线做垂线映射得到 //antidiagHasQueen:标记此行之前的哪些副对角线已经放置了皇后, // 如有放置在(r,c)坐标上的皇后则antidiagHasQueen[r+c]=1;->棋盘格子向其做垂线映射得到 private void backtracking(int row,int n, int colHasQueen, int diagHasQueen, int antidiagHasQueen){ if(row == n) sum++; else{ for(int i=0;i<n;i++){ boolean isColSafe = ((1<<i)&colHasQueen)==0; boolean isDiagSafe = ((1 << (n - 1 + row - i)) & diagHasQueen)==0; boolean isAntiDiagSafe = ((1 << (row + i)) & antidiagHasQueen)==0; if(isColSafe&&isDiagSafe&&isAntiDiagSafe){ backtracking(row+1, n, (1<<i)|colHasQueen, ((1 << (n - 1 + row - i)) | diagHasQueen), (1 << (row + i)) | antidiagHasQueen); } } //运行至此,表示没有找到合适的位置,将会返回到上一级的backtracking语句行, //重新摆放上一个皇后,继续寻找可能得解 } } }
51. N-Queens
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..”]
]
写完上面那个,下面的就好些一点啦~重点是要选好数据结构去存储solutions。
public class Solution { public List<List<String>> solveNQueens(int n) { List<List<String>> result = new ArrayList<List<String>>(); char[][] curSolution = new char ; backtracking(0,n,0,0,0,result, curSolution); return result; } private void backtracking(int row,int n, int colHasQueen, int diagHasQueen, int antidiagHasQueen, List<List<String>> result, char[][] curSolution){ if(row == n){ List<String> cur = new ArrayList<String>(); for(char[] tmp:curSolution){ cur.add(String.valueOf(tmp)); } result.add(cur); } else{ for(int i=0;i<n;i++){ boolean isColSafe = ((1<<i)&colHasQueen)==0; boolean isDiagSafe = ((1 << (n - 1 + row - i)) & diagHasQueen)==0; boolean isAntiDiagSafe = ((1 << (row + i)) & antidiagHasQueen)==0; if(isColSafe&&isDiagSafe&&isAntiDiagSafe){ curSolution[row][i] = 'Q'; backtracking(row+1, n, (1<<i)|colHasQueen, ((1 << (n - 1 + row - i)) | diagHasQueen), (1 << (row + i)) | antidiagHasQueen, result, curSolution); curSolution[row][i]='.'; } } } } }
要学的东西太多了…希望自己每天多打打鸡血,不要像以前那样懒…
相关文章推荐
- SELECT 顺序
- 搭建cadvisor + influxdb + grafana 监控系统
- 编程小练习
- SpringMVC4零配置--web.xml
- selenium-python-常用方法集锦(不断补充)
- 使用python来格式化显示windows错误码
- Android 编程下 Touch 事件的分发和消费机制
- Java环境设置
- Android开发SharedPreferences的使用
- servlet跳转页面两种方式
- Redis自增序列
- 完美解决phpdoc导出文档中@package的warning及Error的错误
- Runtime Message Forwarding
- 【QQ】前端实现QQ会话功能
- CentOS下安装iptables,禁止Solr的8983端口外网访问
- 生成六位不相同的密码
- 杭电4528
- spark性能调优:开发调优
- Python转义字符空格字符
- Unbuntu修改Apache网站根目录