zoukankan      html  css  js  c++  java
  • lintcode 中等题:N Queens N皇后问题

    题目:

    n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。《不同行,不同列,不同对角线》

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

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

    样例

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

    [

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

         "...Q",

         "Q...",

         "..Q."],

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

         "Q...",

         "...Q",

         ".Q.."]

    ]

    挑战

    你能否不使用递归完成?

    解题:

    题意:在n*n的棋盘上,保证n个皇后,不同行,不同列,不同对角线,这样的组合方式有多少种,并求出所以的组合方式。

    在网上看到下面的思路:

    在n*n的矩阵中,n个皇后分别在0-n-1行,也就是说,第i个皇后在第i行是固定的,但是在第多少列?用到回溯法进行解决。

    对第i个皇后,依次考虑0 - n-1列的位置是否合法,若在第k列的位置合法,则再考虑下一个皇后的位置。

    当i==n的时候并且起位置合法,则保存路径上的各个皇后位置。

    如何判断其位置是合法的?

    1.暴力,定义矩阵,对新来的点看是否有和它在相同的行,列,对角线

    2.定义一个保存所在列的矩阵colVals,其下标就是所在的行,colVals[i]的值就是所在的列值。

    显然 不会相同了,只需再考虑列,对角线<正对角线,负对角线>

    列值相同:colVals[i] = colVals[row]  ->也就是在相同的列

    对角线的时候,可以发现这样的规律:|row - i| = |colVals[row] - colVals[i]| 这里要考虑绝对值,有两种情况的。

    其他情况都是合法的。

    参考链接
    Java程序:

    class Solution {
        /**
         * Get all distinct N-Queen solutions
         * @param n: The number of queens
         * @return: All distinct solutions
         * For example, A string '...Q' shows a queen on forth position
         */
        ArrayList<ArrayList<String>> solveNQueens(int n) {
            // write your code here
            ArrayList<String> path = new ArrayList<String>();
            ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
            if( n<0 )
                return result;
            int cols[] = new int[n];
            DFS_helper(n,result,0,cols);
            return result;
            
        }
        public void DFS_helper(int nQueens,ArrayList<ArrayList<String>> result,int row,int[] cols){
            if(row == nQueens ){
                ArrayList<String> path = new ArrayList<String>();
                for(int i = 0;i<nQueens ;i++){
                    String s = "";
                    for(int j = 0;j< nQueens ;j++){
                        if(j == cols[i])
                            s = s + "Q";
                        else
                            s = s + ".";
                    }
                    path.add(s);
                    
                }
                result.add(path);
            }else{
                for(int i = 0;i<nQueens ;i++){
                    cols[row] = i;
                    if(isValid(row,cols))
                        DFS_helper(nQueens,result,row + 1 ,cols);
                }
            }
        }
        public boolean isValid(int row ,int[] cols){
            for(int i=0;i<row;i++){
                if(cols[row] == cols[i] || Math.abs(cols[row] - cols[i]) == row - i)
                return false;
            }
            return true;
        }
    };
    View Code

    总耗时: 1397 ms

    "这类型问题统称为递归回溯问题,也可以叫做对决策树的深度优先搜索(dfs)"

    竟然也叫深度优先搜索。。。

    Python程序:

  • 相关阅读:
    11、sqlite
    10、正则
    9、bs4
    8、异常与import
    7、文件
    6、函数
    4、字典及集合
    3、元组
    1、python基本语法
    shell编程 15 --- shell 脚本调试技巧
  • 原文地址:https://www.cnblogs.com/bbbblog/p/4909454.html
Copyright © 2011-2022 走看看