N-Queens
来源:互联网 发布:淘宝装修图片加热点 编辑:程序博客网 时间:2024/05/23 15:06
这个题花了我很长时间。
原题:
The n-queens puzzle is the problem of placing n queens on ann×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皇后问题(听说很经典,以前没玩过)。规则是nxn的方格里每行每列都有一个皇后(其实每行就限制了每列),她们不在同一行、同一列或者同一个斜线上。一开始只以为不在同一行同一列就行,费了力气写了一个函数。发现问题后添加了最后一项规则,按照以前的思路:它是从n = 4一级一级往上更新答案。但是结果集不完整。后来想到了用类似soduku的回溯方法解决这个问题。
思考过程:
用回溯的思想后,先直接对List<List<String>>进行操作,最后终于能解决,但是对List<List<String>>操作太费时间了,最后果然超时了:
//超时算法 public List<List<String>> solveNQueensTLE(int n) { List<List<String>> ret = new ArrayList<>(); List<String> strings = new ArrayList<>(); strings.add(""); backTrackTLE(ret,strings,0,0,n); return ret; } public void backTrackTLE(List<List<String>> ret,List<String> subRet,int row,int column,int n){ if (column == n) if (!subRet.get(row).contains("Q")) return; else if (row == n - 1){ ret.add(subRet);return; } else { row++;column = 0; subRet.add(""); } String str = subRet.get(row); String s = str + 'Q'; List<String> newSubRet = new ArrayList<>(); newSubRet.addAll(subRet); if (canPutQTLE(subRet,row,column,n)){ subRet.remove(row);subRet.add(s); backTrackTLE(ret,subRet,row,n,n); } String s1 = str + '.'; newSubRet.remove(row);newSubRet.add(s1); backTrackTLE(ret,newSubRet,row,column + 1,n); } public boolean canPutQTLE(List<String> subRet,int row,int column,int n){ for (int i = 0;i < row;i++) if (subRet.get(i).charAt(column) == 'Q') return false; for (int i = 1;i <= Math.min(row,column);i++) if (subRet.get(row - i).charAt(column - i) == 'Q') return false; for (int i = 0;i <= Math.min(row,n - 1 - column);i++) if (subRet.get(row - i).charAt(column + i) == 'Q') return false; if (column > 0 && subRet.get(row).contains("Q")) return false; return true; }
后来想到用一个一维数组,存放第i行皇后的位置。比如subRet[3] = 2,表示第三行皇后在第二个位置上。思路都是差不多的,不过对数组操作、比较终究是快捷的(见到有强者用位运算记录皇后位置,觉得很厉害,但未能领会)。
解题思路:
详见代码注释。
结果代码:
public List<List<String>> solveNQueens(int n) { int[] subRet = new int[n];//初始化数组,每个数组代表结果的一个解集。数组初始化为零,为了少操作,subRet[i] = 0表示第i行没有皇后,而不是第一个位置上是皇后,subRet[i] = 1表示第一个位置上是皇后 List<List<String>> ret = new ArrayList<>(); backTrack(ret,subRet,0,1,n);//column最小为1 return ret; } public void backTrack(List<List<String>> ret,int[] subRet,int row,int column,int n){ if (column == n + 1)//column越界的情况 if (subRet[row] == 0) return;//说明这一行没有皇后,这个解集是失败的,不再用。return else if (row == n - 1){//解集已经补全了 addIntoResult(ret,subRet,n);//将数组转化为List<List<String>> return; } else { row++;column = 1;//以上情况都不属于,那么变到下一行。 } int[] newSubRet = new int[n]; newSubRet = Arrays.copyOf(subRet,n);//复制一个解集,用于在当前位置放'Q' if (canPutQ(newSubRet,row,column))//判断是否可以放'Q' backTrack(ret,newSubRet,row,n + 1,n);//如果能,调到下一行 backTrack(ret,subRet,row,column + 1,n);//不能放的情况,向后走 } public void addIntoResult(List<List<String>> ret,int[] subRet,int n){ List<String> sub = new ArrayList<>(); for (int i = 0;i < n;i++){ String s = ""; for (int j = 1;j <= n;j++) if (subRet[i] != j) s += "."; else s += "Q"; sub.add(s); } ret.add(sub); } public boolean canPutQ(int[] subRet,int row,int column){//判断此处是否可以放'Q' if (subRet[row] != 0) return false;//这行有'Q',返回false for (int i = 0;i < row;i++) if (subRet[i] == column || Math.abs(subRet[i] - column) == Math.abs(i - row)) return false;//这一列或者斜线上是否有Q subRet[row] = column; return true; }
阅读全文
0 0
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- N-Queens
- うわさ的一些惯用搭配
- DNS服务器和web服务器配置--自我操作
- 修改DialogFragment的大小和位置
- 客户信息管理系统3—客户信息的增加(二)
- 通过 ulimit 改善系统性能
- N-Queens
- Lemon彻底卸载GCC和G++方法
- File如何转换成MultipartFile
- 2.Nginx切换为守护进程
- elasticsearch5.6.0 logstash数据导入工具
- android webview加载网页时提示NET::ERR_CACHE_MISS的错误
- 谷歌逐步“杀死”HTTP,10月再次行动!
- 3329 顺序表应用5:有序顺序表归并
- postgresql 操作