1. 程式人生 > >LeetCode Day41 N Queens II

LeetCode Day41 N Queens II

採用位運算方法:

row表示當前行列禁位,ld表示當前行左斜線禁位,rd表示當前行右斜線禁位。
row|ld|rd表示當前行所有禁位。其反與upperlim交限制位數。所以當前行所有可用位置表示為:

pos = upperlim & (~(row | ld | rd ));

從右往左進行方案的選擇
p表示最右邊的可用位置

p = pos & (~pos + 1);

佔用該位置後pos=pos-p,進行下一行。此時row = row | pld = (ld | p) << 1 ,rd = (rd | p) >> 1 ,進入下一行遞迴。

 DFS(row|p,(ld|p)<<1,(rd|p)>>1,n,upperlim);

直到某一行沒有可用位置,結束,sum+1。遞迴返回後,檢查pos還有沒有其他可行方案,這即是使用while(pos)的原因。

完整程式碼:

class Solution {
public:
    int totalNQueens(int n) {
        int upperlim=(1<<n)-1;
        int sum=0;
        DFS(0,0,0,sum,upperlim);
        return sum;
        
    }
void DFS(int row,int ld,int rd,int &n,const int upperlim){ int pos,p; if(row==upperlim) n++; else{ pos=upperlim & (~(row | ld | rd));//找到所有可行位置,為0則已不存在可行位置,和upperlim交防止位數變化 while(pos){ p=pos &(~pos+1);//最右邊的可行位置 pos=
pos-p; DFS(row|p,(ld|p)<<1,(rd|p)>>1,n,upperlim); } } } };