LeetCode:N-Queens II

26 篇文章 0 订阅
8 篇文章 0 订阅
/**
Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.

题目大意:N皇后问题,输入N,输出解的个数

经典题目了,皇后们横、竖、斜都不可以碰到
**/

public class Solution {
    public int totalNQueens(int n) {
        //return solve1(n);   //耍流氓
        return solve2(n);
        
    }
    
    //========================== solve1 ================================
    //“我是流氓我怕谁”大法!!
    //跑n=16的时候我的可怜的小手提要跑好久,所以就到这里吧。
    //居然Accept了...
    private int solve1(int n){
        int[] result = {
            1, 1, 0, 0, 2, 
            10, 4, 40, 92, 352, 
            724, 2680, 14200, 73712, 365596, 
            2279184
        };
        
        return result[n];
    }

    //========================== solve2 ================================
    //来个严肃认真的,这段解释是抄网上的,也不知道出处是哪里啦,写的不错就懒得自己写了
    //O(n^3) = O(n) * O(n) * O(n)
    //由于要遍历所有可能性,所以复杂度颇高:遍历行 * 遍历列 * 检查
    //其实就是个深度优先遍历
    /*
      回溯法解N皇后问题
      使用一个一维数组表示皇后的位置
      其中数组的下标表示皇后所在的行
      数组元素的值表示皇后所在的列
      这样设计的棋盘,所有皇后必定不在同一行
     
      假设前n-1行的皇后已经按照规则排列好
      那么可以使用回溯法逐个试出第n行皇后的合法位置
      所有皇后的初始位置都是第0列
      那么逐个尝试就是从0试到N-1
      如果达到N,仍未找到合法位置
      那么就置当前行的皇后的位置为初始位置0
      然后回退一行,且该行的皇后的位置加1,继续尝试
      如果目前处于第0行,还要再回退,说明此问题已再无解
     
      如果当前行的皇后的位置还是在0到N-1的合法范围内
      那么首先要判断该行的皇后是否与前几行的皇后互相冲突
      如果冲突,该行的皇后的位置加1,继续尝试
      如果不冲突,判断下一行的皇后
      如果已经是最后一行,说明已经找到一个解,输出这个解
      然后最后一行的皇后的位置加1,继续尝试下一个解
    */
    
    private int[] place = null;
    private int result = -1;
    
    private int solve2(int n){
        //n长度的数组,存储着每一行的皇后的位置
        place = new int[n];
        //结果的个数
        result = 0;
        
        //递归求解
        loop(n, 0);
        
        return result;
    }
    private void loop(int n, int depth){
        //如果已经放下最后一个皇后,则解决方案多一个
        if(depth == n){
            result++;
            return;
        }
        
        //在当前行进行遍历,选择不同的列
        for(int i=0; i<n; i++){
            //如果当前列允许放下皇后,那就放下并且递归检查下一个行
            if(checkOK(depth, i)){
                place[depth] = i;
                loop(n, depth+1);
            }
        }
    }
    //检查在当前的depth行的第i列是否可放皇后
    private boolean checkOK(int depth, int col){
        for(int i=0; i<depth; i++)
            if(place[i]==col                        //同一列
                    || place[i]+(depth-i) == col    //右斜线
                    || place[i]-(depth-i) == col)   //左斜线
                return false;
        
        return true;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值