代码改变世界

[LeetCode] 51. N-Queens_Hard tag: DFS, backtracking

2019-05-24 10:22  Johnson_强生仔仔  阅读(237)  评论(0编辑  收藏  举报

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.

Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'and '.' both indicate a queen and an empty space respectively.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

其实我们可以看成实际上是求符合某些条件的[1, 2, 3, ... n] 的permutation[LeetCode] 47. Permutations II_Medium tag: DFS, backtracking,而条件就是要Q不在一条斜线上,利用[LeetCode] 系统刷题7_Array & numbers中的一条斜线上的条件来判断,另外有个函数来画puzzle, 会利用到''.join(strList) = 'abcd'  if strList = ['a', 'b', 'c', 'd']

时间复杂度 = 方案总数 * 构造方案所需时间

O( n ! * n)

 

Code:

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        nums = [i for i in range(n)]
        ans = []
        self.helper(nums, ans, [])
        return ans
    

    def helper(self, nums: List[int], ans: List[List[str]], temp: List[int]):
        if not nums:
            ans.append(self.generatePuz(temp))
        for i in range(len(nums)):
            if self.isValid(temp, nums[i]):
                self.helper(nums[:i] + nums[i + 1:], ans, temp + [nums[i]])
        
    

    def isValid(self, nums: List[int], add_num: int) -> bool:
        add_r = len(nums)
        add_c = add_num
        for r, c in enumerate(nums):
            if r + c == add_r + add_c or r - c == add_r - add_c:
                return False
        return True
    
    def generatePuz(self, nums: List[int]) -> List[str]:
        n = len(nums)
        puz = []
        for num in nums:
            cur_r = ""
            for i in range(n):
                cur_r += 'Q' if i == num else '.'
            puz.append(cur_r)
        return puz