N-Queens II

题目:Now, instead outputting board configurations, return the total number of distinct solutions.


思路:回溯法和二进制法

二进制法可能是目前最快的算法。

本质上来讲,这两题没啥区别。只是再写一遍。

首先我需要判断是否合适,行不需要判断,只需要判断列的和两个对角线的。

判断列是在某一列,就1<<colIndex,这样,我每次只需要和原来的colflag-and一下,比如原来是11000000,现在来了一个新的00001000,这个时候and一下是0,说明有效。至于两条对角线,使用同样的方法。只不过在标志是哪条对角线,使用了一些技巧。

接下来就是满足条件,就更新,方法是并上原来的状态。

取消的时候就是一个数学逻辑变换。

这里的queenHelper函数的一个变换就是,当满足8个的时候,返回1,原来是存入堆栈。在程序中一个关键的就是满足条件count要加上后来start+1的情况。



代码:

//切记,本题目还有一种位比较法,可以很快输出有多少个。

class Solution1 {
private:
    //https://leetcode.com/problems/n-queens-ii/
    int colFlag;//代表列
    int diagFlag1;//index=i+j
    int diagFlag2;//index=n-1+i-j
    
    bool isValid(int rowIndex,int colIndex,int n){
        //行不需要判断,因为我是按照行走的
        //为0说明有效
        if( (1<<colIndex)&colFlag ){
            //为1 无效
            return false;
        }
        if( (1<<(rowIndex+colIndex))&diagFlag1  ){
            return false;
        }
        if( (1<<(n-1+rowIndex-colIndex) ) & diagFlag2 ){
            return false;
        }
        return true;
    }
    
    void setFlag(int rowIndex,int colIndex,int n){
        colFlag   |=(1<<colIndex);
        diagFlag1 |=(1<<(rowIndex+colIndex));
        diagFlag2 |=(1<<(n-1+rowIndex-colIndex));
    }
    
    
    void unsetFlag(int rowIndex, int colIndex, int n) {
        colFlag &= ~(1 << colIndex);
        diagFlag1 &= ~(1 << (rowIndex + colIndex));
        diagFlag2 &= ~(1 << (n + rowIndex - colIndex - 1));
    }
    
    int queenHelper(int n, vector<string> &answer, vector<vector<string> > &result) {
        int rowIndex = answer.size();

        if (rowIndex == n) {
            result.push_back(answer);
            return 1;
        }
        int count=0;
        answer.push_back(string(n, '.'));
        for (int i = 0; i < n; i++) {
            if (isValid(rowIndex, i, n)) {
                setFlag(rowIndex, i, n);
                answer.back()[i] = 'Q';
                count+=queenHelper(n, answer, result);//每一次迭代或者说是递归调用会有新的count生成,但是只是返回值,最终还是
                                                      //所有的count值。
                answer.back()[i] = '.';
                unsetFlag(rowIndex, i, n);
            }
        }
        answer.pop_back();
        return count;
    }

public:
    int totalNQueens(int n) {
        // https://oj.leetcode.com/problems/n-queens/

        colFlag = diagFlag1 = diagFlag2 = 0;
        vector<vector<string> > result;
        vector<string> answer;
        
        return queenHelper(n, answer, result);
        
    }
};


posted @ 2015-10-11 00:01  JSRGFJZ6  阅读(113)  评论(0编辑  收藏  举报