輸入:4
輸出:[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解釋: 4 皇后問題存在兩個不同的解法。
提示:
- 皇后彼此不能相互攻擊,也就是說:任何兩個皇后都不能處於同一條橫行、縱行或斜線上。
這是一道比較經典的回溯演算法題
本題的思路通過迴圈N項,依次判斷是否可放置Q,通過hasQueen判斷縱行和左上,右上斜線是否存在Q,不存在則放置Q繼續回溯下一行放置Q位置直到N項都放滿,存在則跳過當前行列
public $NQueens = [];
function solveNQueens($n) {
$arr = array_fill(0,$n,array_fill(0,$n,'.'));
$this->flashBack($arr,$n,0);
return $this->NQueens;
}
function flashBack($arr,$n,$i)
{
if ($i == $n){
$tmp = [];
foreach($arr as $item){
$tmp[] = implode('', $item);
}
$this->NQueens[] = $tmp;
return;
}
for ($j=0;$j<$n;$j++){
if ($this->hasQueen($n,$arr,$i,$j)){
continue;
}
//回溯
$arr[$i][$j] = 'Q';
$this->flashBack($arr,$n,$i+1);
$arr[$i][$j] = '.';
}
}
public function hasQueen($n,$arr,$row,$col)
{
// 同一行不存在衝突,無需處理
// 左下和右下此時為空,無需處理
// 同一列
for ($i=0;$i<$n;$i++){
if ($arr[$i][$col] == 'Q'){
return true;
}
}
// 右上,row - 1, col + 1
$i = $row - 1;
$j = $col + 1;
for (; $i >= 0 && $j < $n; --$i, ++$j) {
if ($arr[$i][$j] == 'Q') return true;
}
// 左上, row - 1, col - 1
$i = $row - 1;
$j = $col - 1;
for (; $i >= 0 && $j >= 0; --$i, --$j) {
if ($arr[$i][$j] == 'Q') return true;
}
return false;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結