1. 程式人生 > >leetcode52. N-Queens II/37. Sudoku Solver

leetcode52. N-Queens II/37. Sudoku Solver

題目描述

經典的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

題目描述

數獨問題。未填充的格子用"."表示,原地修改數獨,無需返回。

例子

思想 1 - 停止填充條件為,board中所有元素都不是"." - findEmpty(); 2 - 主函式,遍歷數字1-9,檢查行衝突、列衝突和 3×33 \times 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