LintCode N皇后问题

n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。

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

每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。

样例
对于4皇后问题存在两种解决的方案:

[

[".Q..", // Solution 1

 "...Q",

 "Q...",

 "..Q."],

["..Q.", // Solution 2

 "Q...",

 "...Q",

 ".Q.."]

]

题目要求的意思就是每一行,每一列,每一斜行的皇后不能多于1个。
递归。还是和LintCode 电话号码的字母组合思想类似。
假设是4皇后问题,那么每一行可以放皇后的位置有4个(即每一列)。递归在每一行放皇后,最后一行放完之后,就是一个可能的解(还没有检查是否符合规则),用二维数组存放。然后对所有的解在检查规则,每一列,每一斜。写完代码之后,在LintCode上面超时了(感觉是枚举了所有的可能,然后又对每种检查一遍的原因)。

然后在网上参考别人的文章,可以采用一维数组来存解。a[i]表示第i行的皇后放在第a[i]列。这在检查规则时候更容易。然后不再是枚举出所有可能的解之后再检查,而是每一行放置皇后时,就检查。看代码:

public class Solution {
    /*
     * @param n: The number of queens
     * @return: All distinct solutions
     */
    public List<List<String>> solveNQueens(int n) {
        // write your code here
        List<List<String>> result=new ArrayList<List<String>>();//存放最终所有结果
        List<Integer> tempResult=new ArrayList<Integer>();//存放某一个结果
        recursion(result,tempResult,n);
        return result;
    }
    public static int recursion(List<List<String>> result,List<Integer> tempResult,int n){
        if(tempResult.size()==n){//如果长度等于n,就是所有皇后放完了,就存到result中。
            List<String> s=new ArrayList<String>();
            for(int i=0;i<n;i++){
                String row="";
                for(int j=0;j<n;j++){
                    if(tempResult.get(i)==j){
                        row+="Q";
                    }
                    else{
                        row+=".";
                    }
                }
                s.add(new String(row));
            }
            result.add(new ArrayList<String>(s));   
            return 1;
        }
        for(int i=0;i<n;i++){//每一行可以放在n列中的任意一列
            boolean flag=true;
            for (int j=0;j<tempResult.size();j++){
                    int absTemp1=j-tempResult.get(j);
                    int absTemp2=tempResult.get(j)+j;
                    if((absTemp1==tempResult.size()-i) || (absTemp2==tempResult.size()+i)){
                        flag=false;
                        break;
                    }
            }
            if((!tempResult.contains(i))&&flag){    
                    tempResult.add(new Integer(i));     
            }
            else{
                continue;
            }
            recursion(result,tempResult,n);
            tempResult.remove(tempResult.size()-1);
        }
        return 1;
    }
}

说一下判断斜行的问题,之前用二维数组时候,就是遍历所有的斜行,统计每一斜行的皇后个数(O(n2))。用一维数组时,观察可以发现在同一斜行上的所有位置,其行-列(\)的值 或行+列(/)的值都相等,所以O(n)就可以判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值