n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

image

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

示例:

输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],

["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

private ArrayList<List<String>> ret=new ArrayList();
public List<List<String>> solveNQueens(int n) {
    List<String> list=new ArrayList();   
    for(int i=0;i<n;i++){
        String s="";
        for(int j=0;j<n;j++) s+=".";
        list.add(s);
    }
    helper(n,0,list);
    return ret;
}

public void helper(int n,int i,List<String> list) {
    if(i==n){
        ret.add(new ArrayList(list));
        return;
    }
    for(int j=0;j<n;j++){
        boolean isValid=true;
        for(int k=0;k<n;k++){
            if(list.get(k).charAt(j)=='Q'){
                isValid=false;
                break;
            }
            if(list.get(i).charAt(k)=='Q') {
                isValid=false;
                break;
            }
        }
        if(!isValid) continue;
        for(int i1=i,j1=j;i1<n && j1<n;i1++,j1++){
            if(list.get(i1).charAt(j1)=='Q') {
                isValid=false;
                break;
            }
        }
        if(!isValid) continue;
        for(int i1=i,j1=j;i1>=0 && j1<n;i1--,j1++){
            if(list.get(i1).charAt(j1)=='Q') {
                isValid=false;
                break;
            }
        }
        if(!isValid) continue;
        for(int i1=i,j1=j;i1<n && j1>=0;i1++,j1--){
            if(list.get(i1).charAt(j1)=='Q') {
                isValid=false;
                break;
            }
        }
        if(!isValid) continue;
        for(int i1=i,j1=j;i1>=0 && j1>=0;i1--,j1--){
            if(list.get(i1).charAt(j1)=='Q') {
                isValid=false;
                break;
            }
        }
        if(isValid) {
            list.set(i,list.get(i).substring(0,j)+"Q"+list.get(i).substring(j+1));
            helper(n,i+1,list);
            list.set(i,list.get(i).substring(0,j)+"."+list.get(i).substring(j+1));
        }
    }
}

这道题和数独那道题比较像,在判断当前数据是否合理的时候可以直接使用之前缓存的数据,这样效率更高

private List<List<String>> ret=new ArrayList();
private char[][] chars;
private boolean[] v0;
private boolean[] v1;
private boolean[] v2;
public List<List<String>> solveNQueens(int n) {
    chars=new char[n][n];
    for(int i=0;i<n;i++) Arrays.fill(chars[i],'.');
    v0=new boolean[n];
    v1=new boolean[2*n-1];
    v2=new boolean[2*n-1];
    helper(n,0);
    return ret;
}
public void helper(int n,int i){
    if(n==i){
        List<String> list=new ArrayList();
        for(char[] row:chars) list.add(new String(row));
        ret.add(list);
        return;
    }
    for(int j=0;j<n;j++){
        if(v0[j]||v1[i+j]||v2[i-j+n-1]) continue;
        v0[j]=v1[i+j]=v2[i-j+n-1]=true;
        chars[i][j]='Q';
        helper(n,i+1);
        v0[j]=v1[i+j]=v2[i-j+n-1]=false;
        chars[i][j]='.';
    }
}

程浩
21 声望2 粉丝

« 上一篇
50. Pow(x, n)
下一篇 »
52. N皇后 II