LeetCode 51. 【N皇后】go语言版

2020/04/30 算法 共 1550 字,约 5 分钟

题目描述

设计一种算法,打印 N 皇后在 N × N 棋盘上的各种摆法,其中每个皇后都不同行、不同列,也不在对角线上。这里的”对角线”指的是所有的对角线,不只是平分整个棋盘的那两条对角线。 示例:
输入:4
输出:[[“.Q..”,”…Q”,”Q…”,”..Q.”],[”..Q.”,”Q…”,”…Q”,”.Q..”]]
解释: 4 皇后问题存在如下两个不同的解法。
[
 [“.Q..”,  // 解法 1
  “…Q”,
  “Q…”,
  “..Q.”],
 [”..Q.”,  // 解法 2
  “Q…”,
  “…Q”,
  “.Q..”]
]
链接:https://leetcode-cn.com/problems/eight-queens-lcci

解题思路

  • 经典的回溯算法题,回溯算法有点像《从零开始的异世界生活》,其实就是不停的选择,如果选择错误那么就回到过去重新选择直到达到我们的目的
  • 这里设计的核心是使用一个维数组表达一组结果,使用该数组的下标表示行号,值表示列。这样 就能定位放置皇后的位置了
  • 首先我们一行一行的去递归查找皇后的位置,先从第一行开始,如果找到位置就记录到数组然后继续 下一行,直到在最后一行找到位置说明我们成功找到了一组解。如果找不到位置就回溯到上一个分支继续往下查找结果
  • 最后我们将结果保存到结果数组

code

//用来存放一组结果,下标为行,值为列,存储Q的位置
var temp []int
//存储最终结果数组
var res [][]string
var N int

func solveNQueens(n int) [][]string {
	N = n
	temp = make([]int, N)
	for i := 0; i < N; i++ {
		temp[i] = -1
	}
	res =[][]string{}
	findCurrentRowPosition(0)
	return res
}

func findCurrentRowPosition(row int) {
	//遍历到最后一行,对结果进行存储
	if row == N {
		save(temp)
		return
	}
	for column := 0; column < N; column++ {
		//如果该位置可以放置,则放置完以后检查下一行
		if isOk(row, column) {
			temp[row] = column
			findCurrentRowPosition(row + 1)
		}
	}
}

//检查该位置是否可以放置
func isOk(row int, column int) bool {
	preColumn := column - 1
	nextColumn := column + 1
	for i := row - 1; i >= 0; i-- {
		//检查正上方是否有棋子
		if temp[i] == column {
			return false
		}
		//检查左上方对角线是否有棋子
		if preColumn >= 0 {
			if temp[i] == preColumn {
				return false
			}
		}
		//检查右上方对角线是否有棋子
		if nextColumn < N {
			if temp[i] == nextColumn {
				return false
			}
		}
		preColumn--
		nextColumn++
	}

	return true
}

//用来存储最终结果
func save(temp []int) {
	var tRes = make([]string, N)
	//处理每一行
	for row, column := range temp {
		//处理每一列
		for i := 0; i < N; i++ {
			if column == i {
				tRes[row] += "Q"
			} else {
				tRes[row] += "."
			}
		}
	}
	res = append(res, tRes)
}

文档信息

Search

    Table of Contents