Swift BackTracking N-queen
Posted
技术标签:
【中文标题】Swift BackTracking N-queen【英文标题】: 【发布时间】:2019-06-24 11:56:34 【问题描述】:我正在尝试解决 N 皇后问题。 你可以在https://leetcode.com/problems/n-queens/找到问题。
对于回溯,我了解到我们可以用三个键来解决问题:
做出选择
约束
目标
所以我想出了这个解决方案:
func solveNQueens(_ n: Int) -> [[String]]
typealias ChessBoard = [[Int]]
var result = Set<ChessBoard>()
func getIndexsOfDiagonal(row:Int,column:Int) -> [(row:Int,col:Int)]
var indexs = [(Int,Int)]()
var rowIndex = row
var colIndex = column
while rowIndex < n && colIndex < n
indexs.append((rowIndex,colIndex))
rowIndex += 1
colIndex += 1
rowIndex = row
colIndex = column
while rowIndex >= 0 && colIndex >= 0
indexs.append((rowIndex,colIndex))
rowIndex -= 1
colIndex -= 1
rowIndex = row
colIndex = column
while rowIndex >= 0 && colIndex < n
indexs.append((rowIndex,colIndex))
rowIndex -= 1
colIndex += 1
rowIndex = row
colIndex = column
while rowIndex < n && colIndex >= 0
indexs.append((rowIndex,colIndex))
rowIndex += 1
colIndex -= 1
return indexs
func placeQuees(chessboard:ChessBoard,row:Int,column:Int) ->ChessBoard
var newChessBorad = chessboard
//set row
for index in 0..<n
newChessBorad[row][index] = -1
//set column
for index in 0..<n
newChessBorad[index][column] = -1
//set diagonal
for index in getIndexsOfDiagonal(row:row,column:column)
newChessBorad[index.row][index.col] = -1
newChessBorad[row][column] = 1
return newChessBorad
func solve(chessboard:ChessBoard, queens: Int)
if queens == 0
//Goal
result.insert(chessboard)
for row in 0..<n
for col in 0..<n
//Choices
if chessboard[row][col] == 0
//Constraints
let new = placeQuees(chessboard: chessboard, row: row, column: col)
solve(chessboard: new, queens: queens - 1)
solve(chessboard: Array(repeating: Array(repeating: 0, count: n), count: n), queens: n)
return result.map
//chessboard
$0.map
//row to string
$0.reduce("") string,value in
if value == 1
return string + "Q"
else
return string + "."
但是时间有限。所以我想知道我的解决方案是否使用回溯?出了什么问题,我该如何改进解决方案,我们如何解决回溯问题?什么定义了回溯?
非常感谢。
【问题讨论】:
@vacawama 我知道这个想法,但我想知道我的解决方案出了什么问题。谢谢。 我投票结束这个问题,因为它属于CodeReview SE,因为它关注如何改进已经工作的代码。在那里提出您的问题之前,请确保您检查了该网站的帮助页面,确保您根据该网站的规则以符合主题的方式提出您的问题。 【参考方案1】:您的解决方案是回溯。当它无法再找到可用空间 (chessboard[row][col] == 0
) 来放置皇后时,它会回溯。由于它正在寻找所有可能的解决方案,因此它也会在找到解决方案后回溯并将其插入result
。
您的解决方案只是在每次调用solve
时尝试过多的试用职位。请注意,任何给定行上只能有一个皇后。因此,solve
可以通过在每次调用solve
时仅尝试将皇后放在单行上来更有效地工作。在第一次调用solve
时,尝试将皇后放在row 0
上。然后,您将只考虑n
可能的展示位置,而不是n * n
。在第二次拨打solve
时,尝试将女王放在row 1
上。当前的row
可以计算为n
减去剩余的皇后数或n - queens
。
通过这个轻微的修改,你的代码在提交给 LeetCode 时运行得更快并且成功通过:
func solve(chessboard:ChessBoard, queens: Int)
if queens == 0
//Goal
result.insert(chessboard)
else
let row = n - queens
for col in 0..<n
//Choices
if chessboard[row][col] == 0
//Constraints
let new = placeQuees(chessboard: chessboard, row: row, column: col)
solve(chessboard: new, queens: queens - 1)
【讨论】:
以上是关于Swift BackTracking N-queen的主要内容,如果未能解决你的问题,请参考以下文章
迷宫问题(MazePath)的求解——利用回溯法(backtracking)
Jan 23 - Gray Code; BackTracking;
Jan 24 - Restore Ip Addresses; BackTracking; Recursion; DFS;