<leetcode>NO.52 N皇后二

皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

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

示例:

输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
class Solution {
public:
    int totalNQueens(int n) {
        int ret=0;
        if(n==0)return ret;
        //第一位保存当前行最大可填充位置选择数目
        //第二位保存当前行已填充次数
        //第三位保存当前行填充位置
        vector<vector<int>> state(n,vector<int>(3,-1));
        state[0][0]=n;
        state[0][1]=0;
        //n*n的棋盘,一颗棋子填充进入后, 位置斜向下对角线和正下方同一列 计数+1
        //上一次填充完毕后,当前行计数为0的位置可填充棋子
        vector<vector<int>> board(n,vector<int>(n,0));
        while(1)
        {
            int pos=n-1;
            for(;pos>=0;pos--)
            {//查找初始填充位置
                if(state[pos][0]>0&&state[pos][1]<state[pos][0])
                {
                    break;
                }
            }
            if(pos<0)
            {//填充完毕
                break;
            }
            else
            {
                if(state[pos][1]>0)
                {//清除记录
                    for(int i=pos,j=state[pos][2];i<n&&j>=0;i++,j--)
                    {//左斜
                        board[i][j]--;
                    }
                    for(int i=pos+1,j=state[pos][2]+1;i<n&&j<n;i++,j++)
                    {//右斜
                        board[i][j]--;
                    }
                    for(int i=pos+1;i<n;i++)
                    {
                        board[i][state[pos][2]]--;
                    }
                }
                int find=0;
                for(int i=state[pos][2]+1;i<n;++i)
                {
                    if(board[pos][i]==0)
                    {
                        state[pos][1]++;
                        state[pos][2]=i;
                        find=1;
                        //更新记录
                        for(int k=pos,j=state[pos][2];k<n&&j>=0;k++,j--)
                        {//左斜
                            board[k][j]++;
                        }
                        for(int k=pos+1,j=state[pos][2]+1;k<n&&j<n;k++,j++)
                        {//右斜
                            board[k][j]++;
                        }
                        for(int k=pos+1;k<n;k++)
                        {//正下
                            board[k][state[pos][2]]++;
                        }
                        break;
                    }
                }
                if(!find)
                {
                    state[pos][0]=0;
                    state[pos][1]=0;
                    state[pos][2]=0;
                    continue;
                }
                for(int k=pos+1;k<n;k++)
                {//初始化pos+1至n-1
                    if(state[k][1]>0)
                    {
                        for(int i=k,j=state[k][2];i<n&&j>=0;i++,j--)
                        {//左斜
                            board[i][j]--;
                        }
                        for(int i=k+1,j=state[k][2]+1;i<n&&j<n;i++,j++)
                        {//右斜
                            board[i][j]--;
                        }
                        for(int i=k+1;i<n;i++)
                        {//正下
                            board[i][state[k][2]]--;
                        }
                    }
                    state[k][0]=0;
                    state[k][1]=0;
                    state[k][2]=0;
                }
                for(int k=pos+1;k<n;k++)
                {
                    state[k][0]=n-k;
                    find=0;
                    for(int i=0;i<n;++i)
                    {
                        if(board[k][i]==0)
                        {
                            state[k][1]++;
                            state[k][2]=i;
                            find=1;
                            //更新记录
                            for(int g=k,j=state[k][2];g<n&&j>=0;g++,j--)
                            {//左斜
                                board[g][j]++;
                            }
                            for(int g=k+1,j=state[k][2]+1;g<n&&j<n;g++,j++)
                            {//右斜
                                board[g][j]++;
                            }
                            for(int g=k+1;g<n;g++)
                            {//正下
                                board[g][state[k][2]]++;
                            }
                            break;
                        }
                    }
                    if(!find)
                    {//无法找到放置位置,退出pos+1循环
                        state[k][0]=0;
                        break;
                    }
                }
                if(state[n-1][1]==1)
                {
                    ret++;
                }
            }
        }
        return ret;
    }
};

执行用时 : 8 ms, 在N-Queens II的C++提交中击败了90.42% 的用户

内存消耗 : 8.8 MB, 在N-Queens II的C++提交中击败了28.07% 的用户

1.这题就没有多想了,直接在上个问题的基础上把返回值变成总数目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值