この説明は理解しやすいです:バックトラック方法とN-クイーンの問題
。N-クイーンの問題。タイトルは、N個のクイーンがN * Nチェスボードに配置されることを意味します。これらのN個のクイーンは「平和に暮らす」必要があります。2つのクイーンが同じ列にある場合、同じ列、または同じ対角線の場合、2人の女王が戦います。
まず、この問題の解決策を直感的に理解しましょう。最初の行からクイーンを配置します。各行を配置するときは、現在の列をクイーンと一緒に配置できるかどうかを確認する必要があります。配置できる場合は、OK、次の行に移動します。配置できない場合は、行の次の列を入力して判断します。行の終わりまでクイーンを配置できない場合は、前の行に戻り、前の行のクイーンの位置を変更して、上記の操作を繰り返します。最後の行に移動してクイーンを配置できる場合、これは実行可能な解決策です。最初の行のクイーンが終了列に到達すると、検索プロセス全体が終了します。
アルゴリズムのアイデアは理解しやすいですが、コードに変換するのはそれほど簡単ではありません
必要な変数:
- column:まず、配置されたクイーンの位置を記録する1次元配列が必要です。array要素の添え字は行数を示し、array要素の値は列数を示します。配列を列として示します。
- 行、列:現在の位置がどの行と列にあるか
- 合計:ソリューションの数を記録します
- n:女王の数
ステップ:
- 補助関数isOK(row、col):現在の位置でクイーンを配置できるか、現在の行数の前にクイーンをトラバースできるか、クイーンがある場合、列数が現在の列数(同じ列)に等しいか、行数の絶対値が等しいかどうかを判別します。列数の差の絶対値(同じ対角線)、競合することを示します
def isOk(self,row, col):
for i in range(0, row):
if(col == self.column[i] or abs(row - i) == abs(col - self.column[i])):
return False
return True
- 主な機能:最初に現在の行が最後の行であるかどうかを判断し、そうでない場合はソリューションに1を追加し、そうでない場合は現在の行の適切な位置を見つけ、適切な場合は次の行を入力し、適切でない場合は検索を続けます。行が適切な位置を見つけることができない場合、現在のループは終了し、前の行のキューループにフォールバックします
def queue(self, row):
if(row == self.n):
self.total += 1
else:
for col in range(0, self.n):
self.column[row] = col
if(self.isOk(row, col)):
self.queue(row + 1) # 进入下一行
完全なコードは次のとおりです。
class Solution:
def isOk(self,row, col):
for i in range(0, row):
if(col == self.column[i] or abs(row - i) == abs(col - self.column[i])):
return False
return True
def queue(self, row):
if(row == self.n):
self.total += 1
else:
for col in range(0, self.n):
self.column[row] = col
if(self.isOk(row, col)):
self.queue(row + 1)
def totalNQueens(self, n: int) -> int:
self.total = 0
self.n = n
self.column = [0] * self.n
self.queue(0)
return self.total