python刷题-n皇后(回朔法递归)

1.题目

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

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

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

示例 1:


输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例 2:

输入:n = 1
输出:[["Q"]]
 

提示:

1 <= n <= 9

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

2.个人题解

时间复杂度:小于n!

空间复杂度:n2

class Solution:
    def solveNqueen(self, n: int):  # :表示参数类型
        solve = []
        a = set()
        b = set()
        c = set()
        bool_Queen = [[False] * n] * n
        def addresult(n :int):
            result = []
            for i in range(n):
                temp = ["Q" if bool_Queen[i][j] else "." for j in range(n)]
                result.append("".join(temp))  # "".join()生成的是字符串
            return result
        def backtrack(row: int):
            if row == n:
                final = addresult(n)
                solve.append(final)  # 列表不存在本地变量的说法
            else:
                for i in range(n):
                    if i in a or i - row in b or i + row in c:
                        continue
                    else:
                        # 列表不像Numpy 无法对切片赋值 但可以从列表推导式的方向去思考
                        # bool_Queen[row][:] = False 报错
                        bool_Queen[row] = [False] * n  # 对每一行进行初始化
                        bool_Queen[row][i] = True
                        a.add(i)
                        b.add(i - row)
                        c.add(i + row)
                        backtrack(row + 1)  # 回溯法递归
                        a.remove(i)  # 清除记忆
                        b.remove(i - row)
                        c.remove(i + row)

        backtrack(0)
        return solve


debug = Solution()
a = debug.solveNqueen(4)
for i, solve in enumerate(a):
    print("第%d种情况:" % i, solve, "\n")

3.官方题解

回朔法,实则是深度优先遍历,别忘了回朔时的初始化

### https://leetcode-cn.com/problems/n-queens/solution/nhuang-hou-by-leetcode-solution/
### 回朔法(递归), 官方题解


class Solution:
    def solveNQueens(self, n: int):  # :表示参数类型
        def generateBoard():
            board = list()
            for i in range(n):
                row[queens[i]] = "Q"
                board.append("".join(row))  # 针对str的操作,可以将“”中的值插入每个元素之间
                row[queens[i]] = "."  # 还原
            return board

        def backtrack(row: int):
            if row == n:  # 这里是走完一圈后记录结果 也是递归出口 # row == n 相当于行超出了,比如总共n行 这里表示的意思是递归到第n+1行,所以退出
                board = generateBoard()
                solutions.append(board)
            else:
                for i in range(n):
                    if i in columns or row - i in diagonal1 or row + i in diagonal2:
                        continue
                    queens[row] = i  # quneens这个不用像下面一样remove,因为这相当于一个temp 只当有正确结果输出的时候他才会起作用
                    columns.add(i)
                    diagonal1.add(row - i)
                    diagonal2.add(row + i)
                    backtrack(row + 1)  # 这里体现回溯, 本来我遇到了个循环的瓶颈:如何进行N次循环以保证每行的多种情况不丢失,这个方法完美结局,
                                        # 对每一行的每种情况往下层递归,然后完成后回到这层时候,通过下面的remove将之前记录的信息删除,回到完成这种情况后的初态

                    columns.remove(i)  # 这个三个要remove因为会对判断操作带来影响
                    diagonal1.remove(row - i)
                    diagonal2.remove(row + i)

        solutions = list()
        queens = [-1] * n  # 注意这里和下面的row不需要二维的数组   因为函数体中的queens[row] = i 是记录每一行皇后的索引
        columns = set()  # 集合
        diagonal1 = set()
        diagonal2 = set()
        row = ["."] * n
        backtrack(0)  # 我们需要查找的是索引为0 -- n-1 行
        return solutions

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值