Golang解决N皇后问题~
问题:n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。不能互相攻击的情况是两个皇后不能在同一直线(横纵)或者同一对角线,只要存在这两种情况均不是解决方案!
例如:
当n等于4的时候可以有两种解,如下:
当n=1的时候,那就刚好只有一个解!
两种输出要求,一种是输出所有N皇后的情况,将结果列出来,另一种就是输出有多少种解。对于这两种不同的输出要求,我们可以采用同一段代码,只需修改其中一部分即可,走,看代码:
输出所有N皇后的情况,用[[".Q…","…Q",“Q…”,"…Q."],["…Q.",“Q…”,"…Q",".Q…"]]的形式输出!
var res [][]string //声明一个全局的存所有情况的二维切片~
func solveNQueens(n int) [][]string {
res = make([][]string,0)//初始化~
//由于字符串底层就是byte数组,所以用二维byte切片做棋盘!并声明初始化大小
chessboard := make([][]byte, n)
//初始化棋盘,全部置为 '.'
for i := 0; i < n; i++ {
chessboard[i] = make([]byte, n)
for j := 0; j < n; j++ {
chessboard[i][j] = '.'
}
}
backTack(chessboard, n, 0) //这里就开始从第一行,开始回溯~
return res
}
func backTack(chessboard [][]byte, n, row int) {
//判断当前的row是否已经到最后一行,是的话说明已经是N皇后的一种情况,并且不会互相攻击
if row == n {
tempboard := make([]string, 0)//创建一个临时字符串切片存储棋盘每一行的内容
for _, v := range chessboard {
//将棋盘每一行内容是byte直接转换成string,然后存入tempboard
tempboard = append(tempboard , string(v))
}
//然后再将这一种情况存入全局的res中
res = append(res, tempboard)
return
}
//如果当前不是最后一行,那么开始判断当前行的每一个位置适不适合放 Q(皇后)!
for col := 0; col < n; col++ {
//如果当前位置不合法,就直接跳过,换下一列
if !isValid(chessboard, n, row, col) {
continue
}
//如果当前位置可以放 Q 那就先置为 Q 然后开始下一行的判断能不能有合法位置放 Q
chessboard[row][col] = 'Q'
backTack(chessboard, n, row+1)
//如果回溯回来后,表明当前位置不能放 Q ,不是一种解,所以重新置为 . ,然后换列继续尝试~
chessboard[row][col] = '.'
}
}
//以下这个函数就是判断当前行,当前列的位置是否适合放一个 Q
func isValid(chessboard [][]byte, n, row, col int) bool {
//通过for循环判断该位置的纵向上面是否有Q,有的话返回false表示不能放 Q
//另外,下面三个for循环均只需要判断上方有没有 Q ,不需要判断下面,
//因为是一行一行的放 Q,下面还没放所以不需要判断
for r := 0; r < row; r++ {
if chessboard[r][col] == 'Q' {
return false
}
}
//判断当前位置的右上方(右斜对角线)有没有 Q
i := row - 1
j := col + 1
for i >= 0 && j < n {
if chessboard[i][j] == 'Q' {
return false
}
i--
j++
}
//判断当前位置的左上方(左斜对角线)有没有 Q
i = row - 1
j = col - 1
for i >= 0 && j >= 0 {
if chessboard[i][j] == 'Q' {
return false
}
i--
j--
}
//正确位置
return true
}
以上就是对于输出所有N皇后情况的解答!那么对于只要输出有多少个解的情况呢,只需改动一小部分代码!如下,看
//只有小小的代码改动!
var count int
func totalNQueens(n int) int {
count = 0
...
}
func backTack(chessboard [][]byte,n,row int){
//不需要保存所有情况的解,只需要累加N皇后的解的数量~
if row == n{
count++
return
}
for col := 0;col < n;col++{
if !isValid(chessboard,n,row,col){
continue
}
chessboard[row][col] = 'Q'
backTack(chessboard,n,row+1)
chessboard[row][col] = '.'
}
}
到这里,就结束了~
N皇后问题还是很好理解的,除了回溯这种方法,还有其他方法可以实现,这里就不一一叙述显得篇幅太长(●ˇ∀ˇ●)
是不是学懂了?不会吧,不会吧,不会还有人这样都看不懂吧!!!
那你就多看几遍多理解几遍~ d=====( ̄▽ ̄*)b
要是本文对你有帮助的话,能不能留下你的小爱心呢~