DFS+回溯专题8 - leetcode52. N-Queens II/37. Sudoku Solver

52. N-Queens II

题目描述

经典的N皇后问题。给定n,返回N皇后问题不同解的数量。

例子

Input: 4
Output: 2

Explanation: There are two distinct solutions to the 4-queens puzzle as shown below.
[
[".Q…", // Solution 1
“…Q”,
“Q…”,
“…Q.”],

["…Q.", // Solution 2
“Q…”,
“…Q”,
“.Q…”]
]

思想

要求 - 任两个皇后都不能处于同一条横行纵行对角线上。

每行肯定仅包含一个queen-坐标(x, y),所以在dfs参数里:
1 - 首先固定横坐标x [取值从n-1到0],遍历所有列y
2 - 列冲突判断记为useY对角线冲突判断记为useXY1,useXY2
3 - 对于对角线冲突,包含两种情况:主对角线冲突x-y相同;辅对角线冲突x+y相同。x和y取值范围均为0-n,故x+y取值范围为0-2n;x-y范围为-n-n → x-y+n范围为0-2n

解法

class Solution(object):
    def totalNQueens(self, n):
        """
        :type n: int
        :rtype: int
        """
        # Row-x, col-y
        self.cnt = 0
        useY = [True] * n
        useXY1, useXY2 = [True] * (2*n),  [True] * (2*n)
        
        self.helper(n-1, useY, useXY1, useXY2, n)
        return self.cnt
        
    def helper(self, x, useY, useXY1, useXY2, n):
        if x == -1:
            self.cnt += 1
            return
        
        for y in range(n):
            if useY[y] and useXY1[x+y] and useXY2[x-y+n]:
                useY[y] = False
                useXY1[x+y] = False
                useXY2[x-y+n] = False
                self.helper(x-1, useY, useXY1, useXY2, n)
                useY[y] = True
                useXY1[x+y] = True
                useXY2[x-y+n] = True

37. Sudoku Solver

题目描述

数独问题。未填充的格子用"."表示,原地修改数独,无需返回。

例子

思想
1 - 停止填充条件为,board中所有元素都不是"." - findEmpty();
2 - 主函数,遍历数字1-9,检查行冲突、列冲突和 3 × 3 3 \times 3 3×3 冲突。checkRow、checkCol和checkSquare。

解法

class Solution(object):
    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: void Do not return anything, modify board in-place instead.
        """
        self.board = board
        self.solve()
        
    def findEmpty(self):
        for r in range(len(self.board)):
            for c in range(len(self.board[0])):
                if self.board[r][c] == '.':
                    return r,c
        return -1, -1
    
    def solve(self):
        r, c = self.findEmpty()
        if r == -1:    # r==-1 and c==-1
            return True
        for num in '123456789':
            if self.checkRow(num, r) and self.checkCol(num, c) and self.checkSquare(num, r, c):
                self.board[r][c] = num
                if self.solve():
                    return True
                self.board[r][c] = '.'

    def checkRow(self, num, r):
        return num not in self.board[r]
    
    def checkCol(self, num, c):
        for r in range(9):
            if self.board[r][c] == num:
                return False
        return True
    
    def checkSquare(self, num, r, c):
        # minRow:r//3 * 3
        r = r // 3 * 3
        c = c // 3 * 3
        for i in range(r, r+3):
            for j in range(c, c+3):
                if self.board[i][j] == num:
                    return False
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值