N皇后-leetcode51

 这道题主要是要判断四个方向:

同行

同列

斜向1:行号加列号相同

斜向2:行号减列号的绝对值相同(也可以不用绝对值,用 +n-1 轮转

class Solution:
    def solveNQueens(self, n):

        ans=[]
        vis=[0]*(2*n-1)    #set() #保存已经访问的行/列/斜(斜向1:行号加列号是不变的;斜向2:行号减列号相同)

        b=[]    #每次当前的选择,也可以用dfs中传入,但是会占用更多空间
        def dfs(step):
            if step==n:
                l=['.'*n for _ in range(n)]
                print(l)
                for i in b:
                    print(i)
                    l[i[0]]=l[i[0]][:i[1]]+'Q'+l[i[0]][i[1]+1:]
                ans.append(l)
                return  #别忘记终止

            for i in range(n):
                if vis[i]:#同行
                    continue
                for j in range(n):
                    if vis[j]:#同列
                        continue
                    if vis[i+j]:#同斜1
                        continue
                    d=abs(i-j)
                    if vis[d]:#同斜2
                        continue

                    b.append([i,j])
                    vis[i]=1
                    vis[j]=1
                    vis[i+j]=1
                    vis[d]=1
                    ''' 用set的话不方便后面恢复现场
                    vis.add(i)
                    vis.add(j)
                    vis.add(i+j)
                    '''
                    dfs(step+1)
                    
                    b.pop()
                    vis[i]=0
                    vis[j]=0
                    vis[i+j]=0
                    vis[d]=0
                    #恢复现场,方便后面分支探索
        dfs(0)
        
        return ans

if __name__=='__main__':
    n=4

    sol=Solution()
    ans=sol.solveNQueens(n)
    print(ans)

我这段代码是错的,因为我没有将行号、列号、斜号进行区分

而且set是可以的,用remove就行

而且斜1和斜2不能共用一个set,否则如果 i+j = abs(i-j) 也就是其一为0的时候,会删两次报错

但是就算我开四个set还是错的

为什么呢?让我们回到题目

同行同列只有一个!那么我两层循环会导致同一行里面有多个皇后,

所以我们得把行号当作step,并在这一行里面找符合要求的位置

我们用cols来存储仍然存活的列

class Solution:
    def solveNQueens(self, n):
        ans = []
        board = ['.' * n for _ in range(n)]

        cols = set()
        diag1 = set()  # row + col
        diag2 = set()  # row - col

        def dfs(row):
            if row == n:
                ans.append(board[:])  # 注意要复制当前棋盘!board是全局变量
                return
            for col in range(n):
                if col in cols or (row + col) in diag1 or (row - col) in diag2:
                    continue
                # 放置皇后
                board[row] = board[row][:col] + 'Q' + board[row][col+1:]
                cols.add(col)
                diag1.add(row + col)
                diag2.add(row - col)

                dfs(row + 1)

                # 回溯
                board[row] = board[row][:col] + '.' + board[row][col+1:]
                cols.remove(col)
                diag1.remove(row + col)
                diag2.remove(row - col)

        dfs(0)
        return ans

if __name__ == '__main__':
    n = 4
    sol = Solution()
    ans = sol.solveNQueens(n)
    for board in ans:
        for row in board:
            print(row)
        print()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值