算法训练 Day 30

LeetCode 51. N 皇后

题目链接:51. N 皇后

思路:回溯经典题,是那种没吃过猪肉也肯定听说过的知名题。其实这道题思路不复杂(相比其他经典的hard题例如接水雨来说),作为困难题主要难在逻辑判断的复杂性、对复杂情况和用例的处理上,此题主要难在皇后是否被攻击的逻辑判断上。还有一些变量的小细节在下方代码中有所注释。

Python版本:

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        res = []
        chess = [["."]*n for _ in range(n)]

        def backtrack(row):
            if row==n:
                tmp = []
                for path in chess:
                    cur_path = "".join(path)
                    tmp.append(cur_path)
                res.append(tmp)

            # 遍历所在行的每一列
            for i in range(n):
                if self.isValid(n, row, i, chess):
                    chess[row][i] = "Q"
                    backtrack(row+1)  # 此处递归的是下一行, 所以是row+1, 而不是i+1
                    chess[row][i] = "."
        
        backtrack(0)
        return res

    def isValid(self, n, row, col, chess):
        # 判断当前列之上是否已经有皇后
        for i in range(row):
            if chess[i][col] == "Q":
                return False

        # 判断左斜上方是否已经有皇后
        i = row-1
        j = col-1
        while i>=0 and j>=0:
            if chess[i][j] == "Q":
                return False
            i -= 1
            j -= 1

        # 判断右斜上方是否已经有皇后
        i = row-1
        j = col+1
        while i>=0 and j<n:
            if chess[i][j] == "Q":
                return False
            i -= 1
            j += 1

        return True    

go版本:

func solveNQueens(n int) [][]string {
    var res [][]string
    chess := make([][]string, n)
    for i:= 0; i < n; i++ {
		chess[i] = make([]string, n)
	}
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			chess[i][j] = "."
		}
	}

    var backtrack func(int)
    backtrack = func(row int) {
        if row==n {
            tmp := make([]string, n)
            for i, v := range chess {
				tmp[i] = strings.Join(v, "")
			}
			res = append(res, tmp)
        }
        for i:=0; i<n; i++ {
            if isValid(n, row, i, chess) {
                chess[row][i] = "Q"
				backtrack(row + 1)
				chess[row][i] = "."
            }
        }
    }

    backtrack(0)
	return res
}

func isValid(n, row, col int, chess [][]string) bool {
	for i := 0; i < row; i++ {
		if chess[i][col] == "Q" {
			return false
		}
	}
	for i, j := row-1, col-1; i >= 0 && j >= 0; i, j = i-1, j-1 {
		if chess[i][j] == "Q" {
			return false
		}
	}
	for i, j := row-1, col+1; i >= 0 && j < n; i, j = i-1, j+1 {
		if chess[i][j] == "Q" {
			return false
		}
	}
	return true
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值