51. N 皇后

100 阅读1分钟

题目: n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

来源:力扣(LeetCode) 链接:leetcode.cn/problems/n-… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法: 方法一:

import "strings"
var ans [][]string
func solveNQueens(n int) [][]string {
	if n == 0 {
		return nil
	}
	ans = make([][]string, 0)
	column := make([]bool, n)
	ldiag := make(map[int]bool)
	rdiag := make(map[int]bool)
	tmp := make([][]string, n)
	for i := 0; i < n; i++ {
		line := make([]string, n)
		for j := 0; j < n; j++ {
			line[j] = "."
		}
		tmp[i] = line
	}
	backtracking(tmp, column, ldiag, rdiag, n, 0)
	return ans
}

func backtracking(tmp [][]string, column []bool, ldiag, rdiag map[int]bool, n, row int) {
	// 0~n-1 行都放置完毕
	if row == n {
		line := make([]string, n)
		for i := 0; i < n; i++ {
			line[i] = strings.Join(tmp[i], "")
		}
		ans = append(ans, line)
		return
	}

	for col := 0; col < n; col++ {
		lDiagIndex, rDiagIndex := row-col, row+col
		if column[col] || ldiag[lDiagIndex] || rdiag[rDiagIndex] {
			continue
		}

		column[col] = true
		ldiag[lDiagIndex] = true
		rdiag[rDiagIndex] = true
		tmp[row][col] = "Q"
		backtracking(tmp, column, ldiag, rdiag, n, row+1) // row + 1不是n+1
		column[col] = false
		ldiag[lDiagIndex] = false
		rdiag[rDiagIndex] = false
		tmp[row][col] = "."
	}

}

方法二:

func solveNQueens(n int) [][]string {
	// result的index为行,value为列,(index, value)为放置皇后的位置
	result := make([]int, n) 
	ans := make([][]string, 0)
	var IsOk = func(row, col int) bool {
		leftUp, rightUp := col - 1, col + 1
		for i := row - 1; i >= 0; i -- {
			// 一行只放一个的,只需要检查列
			if result[i] == col {
				return false
			}
			if leftUp >= 0 && result[i] == leftUp {
				return false
			}
			if rightUp < n && result[i] == rightUp {
				return false
			}
			leftUp --
			rightUp ++
		}
		return true
	}

	var printResult = func(){
		res := make([]string, 0)
		for i := 0; i < n; i ++ {
			row := ""
			for j := 0; j < n; j ++ {
				if result[i] == j {
					row = row + "Q"
				} else {
					row = row + "."
				}
			}
			res = append(res, row)
		}
		ans = append(ans, res)
	}

	var calNQueue func(row int)
	calNQueue = func(row int) {
		if row == n {
			printResult()
			return
		}
		for j := 0; j < n; j ++ {
			if IsOk(row, j) {
				result[row] = j
				calNQueue(row + 1)
			}
		}
	}
	calNQueue(0)
	return ans
}