lintcode33:N皇后问题

描述

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

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

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

样例

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

[

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

     "...Q",

     "Q...",

     "..Q."],

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

     "Q...",

     "...Q",

     ".Q.."]

]

挑战

你能否不使用递归完成?

思路: 首先如果满足每一行,每一列,每一斜边都不冲突的话,那么每一行都只能有一个解。

然后我们来分配每一列的解,每一列的解从1-n依次判断分配,如果满足条件,就分配。这是一个DFS问题。

Java代码如下:

public class N_Queens {
    public static List<List<String>> solveNQueens(int n) {
        // write your code here
        // suppose 每一行一个,现在判断每一列
        List<List<String>> res = new ArrayList<>();
        int[][] arr = new int[n][n];
        helper(0, arr, res, n);
        return res;
    }

    public static void helper(int start, int[][] arr, List<List<String>> res, int n){
        if(start==arr.length){
            // 保存到res
            List<String> list = new ArrayList<>();
            for (int i = 0; i < arr.length; i++) {
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < arr[0].length; j++) {
                    if(arr[i][j]==0){
                        sb.append(".");
                    }else{
                        sb.append("Q");
                    }
                }
                list.add(sb.toString());
            }
            res.add(list);
        }
        for (int i = 0; i < n; i++) {
            if(judge(arr, start, i)) {
                arr[start][i] = 1;
                helper(start + 1, arr, res, n);
                arr[start][i] = 0;
            }
        }
    }

    public static boolean judge(int[][] arr, int start, int i){
        int n = arr.length;
        for (int j = 0; j < arr.length; j++) {
            if(arr[j][i]==1){
                return false;
            }
        }
        // 判断斜着的没有重复的
        int a = start+1, b = i+1;
        while (a<n&&b<n){
            if(arr[a][b]==1){
                return false;
            }
            a++; b++;
        }
        a = start-1; b = i-1;
        while (a>=0&&b>=0){
            if(arr[a][b]==1){
                return false;
            }
            a--; b--;
        }
        a = start+1; b = i-1;
        while (a<n&&b<n&&a>=0&&b>=0){
            if(arr[a][b]==1){
                return false;
            }
            a++; b--;
        }
        a = start-1; b = i+1;
        while (a<n&&b<n&&a>=0&&b>=0){
            if(arr[a][b]==1){
                return false;
            }
            a--; b++;
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(solveNQueens(4));
    }
}

结果:

[[.Q.., ...Q, Q..., ..Q.], [..Q., Q..., ...Q, .Q..]]


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值