Golang-回溯-N皇后

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
要是本文对你有帮助的话,能不能留下你的小爱心呢~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值