这里写目录标题
剪枝
(26.30 跳过)
两种情况:
完全肯定某一分支不是最优解,剪枝
只是局部最优解,优先遍历局部最优解
作业:可以搜一下阿法狗论文的剪枝方法
面试题
51. N-Queens
皇后可以攻击横竖撇捺四个方向
两种思路:
- constrained programming 约束规划
这基本上意味着在每次放置皇后后都要有限制。一个人在棋盘上放置一个皇后,这立即排除了一列,一行和两条对角线,以进一步放置皇后。这将传播约束并帮助减少需要考虑的组合数量。 - backtracking 回溯法
让我们想象一下,一个人在棋盘上放了几个皇后,这样它们就不会互相攻击了。但所选的组合并不是最佳组合,也没有下一个皇后的位置。要做什么吗?回溯。这意味着返回,改变皇后之前的位置,并尝试再次进行。如果这也不起作用,再次返回。
Set用法
python代码:
java代码:
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> res= new ArrayList<List<String>>();
List<String> board = new ArrayList<String>();
for(int i=0;i<n;i++){
board.add("");
}
helper(0, new boolean[n], new boolean[2*n-1], new boolean[2*n-1], board,res);
return res;
}
public void helper(int r, boolean[] cols, boolean[] d1, boolean[] d2,List<String> board,List<List<String>> res){
if(r==cols.length){
//注意:需要实现深复制,否则board一直是引用传递。
List<String> board1 = new ArrayList<String>();
for(int i=0;i<cols.length;i++){
char[] tmp= board.get(i).toCharArray();
board1.add(new String(tmp));
}
res.add(board1);
}
else{
for(int c = 0; c< cols.length ; c++){
int id1= cols.length-1+ r-c;
int id2= r+c;
if(!cols[c] && !d1[id1] && !d2[id2]){
char[] tmp = new char[cols.length];
Arrays.fill(tmp,'.');tmp[c]='Q';
board.set(r,new String(tmp));
cols[c]=true;
d1[id1]=true;
d2[id2]=true;
helper(r+1,cols,d1,d2,board,res);
cols[c]=false;
d1[id1]=false;
d2[id2]=false;
}
}
}
}
}
52. N-Queens II
错误的方法:
class Solution {
public int totalNQueens(int n) {
int res=0;
helper(0, new boolean[n], new boolean[2*n-1], new boolean[2*n-1], res);
return res;
}
public