leetcode-51 N-Queens N皇后问题

问题描述:

The n-queenspuzzle is the problem of placing n queens on an n×n chessboardsuch that no two queens attack each other.


Given an integer n,return all distinct solutions to the n-queens puzzle.

Each solutioncontains a distinct board configuration of the n-queens' placement,where 'Q' and '.' both indicate a queen and an emptyspace 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皇后的问题,最后N个皇后所在的位置一定是在N个不同的行与N个不同的列(同时应该在不同的对角线上);则可以使用一个一维N阶 数组来记录N个皇后的列坐标位置;

 

代码:

public class Solution {
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> result = new ArrayList<>();
        if (n == 0) return result;
        //使用一个n阶的一维数组来记录每一行的Queue列的位置
        int[] indexs = new int[n];
        // 初始化
        for (int i = 0 ; i < indexs.length; i++)
            indexs[i] = -1;
        int i = 0; // i表示行
        while (indexs[0] < n) {
            while (i < n) {
                boolean flag = false;
                // 对每一个可能的值进行遍历,注意回溯情况下,之前遍历的值即可跳过不用遍历
                for (int j = (indexs[i] == -1 ? 0 : indexs[i] + 1); j < n; j++) {
                    if (isValid(indexs, i, j)) {
                        indexs[i] = j;
                        flag = true;
                        break;
                    }
                }
                // 所有情况都不匹配,进行回溯
                if (!flag) {
                    indexs[i] = -1; // 将注意将当前值清空
                    i--;
                }  else i++;
                if (i == -1) // 没有解法的情况
                    return result;
            }

            // 将结果整理输出
            List<String> temp = new ArrayList<>();
            for (i = 0; i < n; i++) {
                StringBuffer sb = new StringBuffer();
                for (int j = 0; j < n; j++) {
                    sb.append(j == indexs[i] ? "Q" : ".");
                }
                temp.add(sb.toString());
            }
            result.add(temp);

            // 回溯到上一步,将最后一步的所得值修改继续进行
            i--;
            indexs[i] ++;

        }

        return result;
    }

    // 判断该位置是否合法
    private boolean isValid(int[] indexs, int i, int j) {

        for (int k = 0; k < i; k++) {
            if (indexs[k] == j) return false; // 列冲突情况
            if ((indexs[k] + k) == (i + j)) return false; // 右对角线冲突情况
            if ((indexs[k] - k) == (j - i)) return false; // 左对角线冲突情况
        }
        return true;
    }

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


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值