github.com/qiuhoude/go-web@v0.0.0-20220223060959-ab545e78f20d/algorithm/leetcode/n-queens_test.go (about)

     1  package leetcode
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  )
     7  
     8  // 51. N皇后
     9  // https://leetcode-cn.com/problems/n-queens/
    10  
    11  func TestSolveNQueens(t *testing.T) {
    12  	t.Log(solveNQueens(4))
    13  }
    14  
    15  func solveNQueens(n int) [][]string {
    16  	ret := make([]int, n)
    17  	var retStr [][]string
    18  	calQueens(0, n, ret, &retStr)
    19  	return retStr
    20  }
    21  
    22  func calQueens(row, n int, ret []int, retStr *[][]string) {
    23  	if row >= n {
    24  		// 找到解
    25  		solve := make([]string, n)
    26  		c := make([]rune, n)
    27  		for i := 0; i < n; i++ {
    28  			for j := 0; j < n; j++ {
    29  				if ret[i] == j {
    30  					c[j] = 'Q'
    31  				} else {
    32  					c[j] = '.'
    33  				}
    34  			}
    35  			solve[i] = string(c)
    36  			fmt.Println(string(c))
    37  		}
    38  		*retStr = append(*retStr, solve)
    39  		fmt.Println("-----------")
    40  		return
    41  	}
    42  	for col := 0; col < n; col++ { // 每行都有n种可能
    43  		if isOk(row, col, n, ret) {
    44  			ret[row] = col                   // 第 row 行的棋子放到了 column 列
    45  			calQueens(row+1, n, ret, retStr) // 如果满足条件就进行尝试下一行
    46  		}
    47  	}
    48  }
    49  
    50  // 检测横竖是否有其他皇后
    51  func isOk(row, col, n int, ret []int) bool {
    52  	lCol := col - 1 // 左边列
    53  	rCol := col + 1 // 右边列
    54  
    55  	for r := row - 1; r >= 0; r-- {
    56  		if ret[r] == col { // 纵向有相同的
    57  			return false
    58  		}
    59  		// 左上对角线
    60  		if lCol >= 0 && lCol == ret[r] {
    61  			return false
    62  		}
    63  		// 右上对角线
    64  		if rCol < n && rCol == ret[r] {
    65  			return false
    66  		}
    67  		lCol--
    68  		rCol++
    69  	}
    70  	return true
    71  }