LeetCode-题目整理【12】:N皇后问题--回溯算法

注意点,语法:
=一定要记得初始化内层数组的长度:board[i] = make([]rune, n),否则就会报出现越界的错

    // 第1步,初始化二维数组,内层数组长度为0,外层为n
	board :=make([][]rune,n)
	for i:=0;i<n;i++{
   
        // 第2步,内层数组初始化为n
        board[i] = make([]rune, n)
        for j:=0;j<n;j++{
   
            board[i][j]='.'
        }
    }

对于byte、rune和string的区别,在初始化二维数组时要注意类型
参考之前写:
https://blog.csdn.net/qq_45927881/article/details/135431178?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22135431178%22%2C%22source%22%3A%22qq_45927881%22%7D


  1. N 皇后
    困难
    按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
    n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
    给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
    每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
    示例 1:
    输入:n = 4
    输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
    解释:如上图所示,4 皇后问题存在两个不同的解法。
    示例 2:
    输入:n = 1
    输出:[[“Q”]]
func solveNQueens(n int) [][]string {
   
	var result [][]string
	// 第1步,初始化二维数组,内层数组长度为0,外层为n
	board := make([][]rune, n)
	for i := 0; i < n; i++ {
   
		// 第2步,内层数组初始化为n
		board[i] = make([]rune, n)
		for j := 0; j < n; j++ {
   
			board[i][j] = '.'
		}
	}

	// 函数 isSafe 用于检查在给定位置 (row, col) 放置皇后是否安全,即不与已放置的皇后冲突。
	var isSafe func(row, col int) bool
	isSafe = func(row, col int) bool {
   
		// 为什么不需要检查同一行是否有皇后:
		//是因为在下面的函数backtrack中,是遍历每一行,即只要每一行放置一个皇后,就到下一行,所以不会存在一行又多个皇后的问题

		// 检查同一列是否有皇后
		for i := 0; i < row; i++ {
   
			if board[i][col] == 'Q' {
   
				return false
			}
		}

		// 检查左上方是否有皇后
		for i, j := row-1, col-1; i >= 0 && j >= 0; i, j = i-1, j-1 {
   
			if board[i][j] == 'Q' {
   
				return false
			}
		}

		// 检查右上方是否有皇后
		for i, j := row-1, col+1; i >= 0 && j < n; i, j = i-1, j+1 {
   
			if board[i][j] == 'Q' {
   
				return false
			}
		}

		return true
	}

	// 函数 backtrack 用于递归地尝试所有可能的皇后放置位置,当放置完成所有皇后时,将当前的棋盘状态加入到结果中。
	var backtrack func(row int)
	backtrack = func(row int) {
   
		if row == n {
   
			var solution []string
			for _, row := range board {
   
				solution = append(solution, string(row))
			}
			result = append(result, solution)
			return
		}

		for col := 0; col < n; col++ {
   
			if isSafe(row, col) {
   
				board[row][col] = 'Q'
				//只要每一行放置一个皇后,就到下一行,所以不会存在一行又多个皇后的问题
				backtrack(row + 1)
				board[row][col] = '.'
			}
		}
	}

	backtrack(0)
	return result
}


下面这道题与上面的区别就是返回的结果,因此只需要将上面返回的结果,变成统计个数,即可解答下面这道题。其余解答过程一摸一样

  1. N 皇后 II
    困难
    n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。
    给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
    示例 1:
    输入:n = 4
    输出:2
    解释:如上图所示,4 皇后问题存在两个不同的解法。
    示例 2:
    输入:n = 1
    输出:1
func totalNQueens(n int) int {
   
    count:=0
	// 第1步,初始化二维数组,内层数组长度为0,外层为n
	board := make([][]rune, n)
	for i := 0; i < n; i++ {
   
		// 第2步,内层数组初始化为n
		board[i] = make([]rune, n)
		for j := 0; j < n; j++ {
   
			board[i][j] = '.'
		}
	}

	// 函数 isSafe 用于检查在给定位置 (row, col) 放置皇后是否安全,即不与已放置的皇后冲突。
	var isSafe func(row, col int) bool
	isSafe = func(row, col int) bool {
   
		// 为什么不需要检查同一行是否有皇后:
		//是因为在下面的函数backtrack中,是遍历每一行,即只要每一行放置一个皇后,就到下一行,所以不会存在一行又多个皇后的问题

		// 检查同一列是否有皇后
		for i := 0; i < row; i++ {
   
			if board[i][col] == 'Q' {
   
				return false
			}
		}

		// 检查左上方是否有皇后
		for i, j := row-1, col-1; i >= 0 && j >= 0; i, j = i-1, j-1 {
   
			if board[i][j] == 'Q' {
   
				return false
			}
		}

		// 检查右上方是否有皇后
		for i, j := row-1, col+1; i >= 0 && j < n; i, j = i-1, j+1 {
   
			if board[i][j] == 'Q' {
   
				return false
			}
		}

		return true
	}

	// 函数 backtrack 用于递归地尝试所有可能的皇后放置位置,当放置完成所有皇后时,将当前的棋盘状态加入到结果中。
	var backtrack func(row int)
	backtrack = func(row int) {
   
		if row == n {
   
			count++
			return
		}

		for col := 0; col < n; col++ {
   
			if isSafe(row, col) {
   
				board[row][col] = 'Q'
				//只要每一行放置一个皇后,就到下一行,所以不会存在一行又多个皇后的问题
				backtrack(row + 1)
				board[row][col] = '.'
			}
		}
	}

	backtrack(0)
	return count
}


// 可以使用回溯算法来解决。

// 算法的时间复杂度取决于皇后的数量,即 O(N!),其中 N 是棋盘的大小。在最坏情况下,需要遍历所有的排列组合。

相关推荐

  1. LeetCode-题目整理12】:N皇后问题--回溯算法

    2024-01-28 06:38:05       39 阅读
  2. LeetCode-题目整理11】:回溯算法

    2024-01-28 06:38:05       21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-28 06:38:05       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-28 06:38:05       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-28 06:38:05       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-28 06:38:05       18 阅读

热门阅读

  1. 【从浅到深的算法技巧】初级排序算法 上

    2024-01-28 06:38:05       35 阅读
  2. 【HDFS】一天一个RPC系列--updateBlockForPipeline

    2024-01-28 06:38:05       35 阅读
  3. ClickHouse(22)ClickHouse集成HDFS表引擎详细解析

    2024-01-28 06:38:05       30 阅读
  4. golang实现一个简单的HTTP server

    2024-01-28 06:38:05       33 阅读
  5. 单元测试——题目十三

    2024-01-28 06:38:05       35 阅读
  6. 系统架构17 - 软件工程(5)

    2024-01-28 06:38:05       31 阅读
  7. vue项目中路由懒加载的三种方式

    2024-01-28 06:38:05       37 阅读