• [Swift]LeetCode51. N皇后 | N-Queens


    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9910395.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    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.

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

    上图为 8 皇后问题的一种解法。

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

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

    示例:

    输入: 4
    输出: [
     [".Q..",  // 解法 1
      "...Q",
      "Q...",
      "..Q."],
    
     ["..Q.",  // 解法 2
      "Q...",
      "...Q",
      ".Q.."]
    ]
    解释: 4 皇后问题存在两个不同的解法。

    24ms
     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         guard n > 0 else {
     4             return []
     5         }
     6         var results = [[String]]()
     7         var cols = [Int]()
     8         cols.reserveCapacity(n)
     9         dfsHelper(n, &cols, &results)
    10         return results
    11     }
    12     
    13     fileprivate func dfsHelper(_ n: Int, _ cols: inout [Int], _ results: inout [[String]]) {
    14         if cols.count == n {
    15             results.append(draw(cols))
    16             return 
    17         }
    18         
    19         for i in 0..<n {
    20             guard isValid(cols, i) else {
    21                 continue
    22             }
    23             cols.append(i)
    24             dfsHelper(n, &cols, &results)
    25             cols.removeLast()
    26         }
    27     }
    28     
    29     
    30     fileprivate func isValid(_ cols: [Int], _ colIndex: Int) -> Bool {
    31         for rowIndex in 0..<cols.count {
    32             if colIndex == cols[rowIndex] {
    33                 return false
    34             }
    35             if cols.count - rowIndex == colIndex - cols[rowIndex] {
    36                 return false
    37             }
    38             if rowIndex - cols.count == colIndex - cols[rowIndex] {
    39                 return false
    40             }
    41         }
    42         return true
    43     }
    44     
    45     fileprivate func draw(_ cols: [Int]) -> [String] {
    46         var result = [String]()
    47         for rowIndex in 0..<cols.count {
    48             var row = ""
    49             for j in 0..<cols.count {
    50                 row += cols[rowIndex] == j ? "Q" : "."
    51             }
    52             result.append(row)
    53         }
    54         return result
    55     }
    56 }

    48ms

     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         var result = [[String]]()
     4         var currB = Array(repeating:String(Array(repeating:".",count:n)),count:n)
     5         var cols = Array(repeating:false,count:n)
     6         var diagnal = Array(repeating:false,count:2*n-1)
     7         var antidiagonal = Array(repeating:false,count:2*n-1)
     8     
     9         helper(&result,&currB,n,0,&cols,&diagnal,&antidiagonal)
    10         return result
    11     }
    12     
    13     func helper(_ result: inout [[String]], _ currB: inout [String], _ n: Int, _ row: Int, _ cols: inout [Bool], _ diagonal: inout [Bool], _ antiDiagonal: inout [Bool]) -> Void {
    14     
    15 
    16         if(row==n) {
    17             result.append(currB)
    18             return
    19         }
    20 
    21         for col in 0..<n {
    22             if(cols[col] || diagonal[row-col+n-1] || antiDiagonal[row+col]) {
    23                 continue
    24             }
    25         
    26             var curr = currB
    27 
    28         
    29             cols[col] = true
    30             diagonal[row-col+n-1] = true
    31             antiDiagonal[row+col] = true
    32         
    33             curr[row] = String(curr[row].prefix(col)) + String("Q") + String(curr[row].dropFirst(col + 1))
    34             helper(&result,&curr,n,row+1,&cols,&diagonal,&antiDiagonal)
    35             cols[col] = false
    36             diagonal[row-col+n-1] = false
    37             antiDiagonal[row+col] = false
    38             curr[row] = String(curr[row].prefix(col)) + String(".") + String(curr[row].dropFirst(col + 1))
    39         }
    40     
    41         return
    42     }
    43 }

    52ms

     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         var result = [[String]]()
     4         var answer = [String]()
     5         nQueens(n: n, p: 0, l: 0, m: 0, r: 0, answer: &answer, result: &result)
     6         return result
     7     }
     8     
     9      private func getNq(index: Int, n: Int) -> String {
    10         var charArr = [Character](repeating: ".", count: n)
    11         charArr[index] = "Q"
    12         return String(charArr)
    13     }
    14     
    15     private func nQueens(n: Int, p: Int, l: Int, m: Int, r: Int, answer: inout [String], result: inout [[String]]) {
    16         if p >= n {
    17             result.append(answer)
    18             return
    19         }
    20         let mask = l | m | r
    21         var i = 0
    22         var b = 1
    23         while i < n {
    24             if mask & b == 0 {
    25                 answer.append(getNq(index: i, n: n))
    26                 nQueens(n: n, p: p+1, l: (l | b) >> 1, m: m | b, r: (r | b) << 1, answer: &answer, result: &result)
    27                 answer.removeLast()
    28             }
    29             i += 1
    30             b <<= 1
    31         }
    32     }
    33 }

    56ms

     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         var res = [[String]]()
     4         var curr = Array(repeating: 0, count: n)
     5         var usedColumn = Array(repeating: false, count: n)
     6         var usedDiagonals = Array(repeating: false, count: n * 2 - 1)
     7         var usedRevDiagonals = Array(repeating: false, count: n * 2 - 1)
     8         generateSolution(n , 0, &curr, &res, &usedColumn, &usedDiagonals, &usedRevDiagonals)
     9         return res
    10     }
    11     
    12     
    13     private func generateSolution(_ n: Int, _ row: Int, _ curr: inout [Int], _ res: inout [[String]], _ usedColumn: inout [Bool], _ usedDiagonals: inout [Bool], _ usedRevDiagonals: inout [Bool]) {
    14         if row == n {
    15             res.append(toList(n, curr))
    16             return
    17         }
    18         
    19         for i in 0..<n {
    20             if isValid(n, row, i, usedColumn, usedDiagonals, usedRevDiagonals) {
    21                 mark(n, row, i, &usedColumn, &usedDiagonals, &usedRevDiagonals)
    22                 curr[row] = i
    23                 generateSolution(n , row + 1, &curr, &res, &usedColumn, &usedDiagonals, &usedRevDiagonals)
    24                 unMark(n, row, i, &usedColumn, &usedDiagonals, &usedRevDiagonals)
    25             }
    26         }
    27     }
    28     
    29     
    30     private func mark(_ n: Int, _ row: Int, _ column: Int, _ usedColumn: inout [Bool], _ usedDiagonals: inout [Bool], _ usedRevDiagonals: inout [Bool]) {
    31         usedColumn[column] = true
    32         usedDiagonals[row + column] = true
    33         usedRevDiagonals[row - column + n - 1] = true
    34     }
    35     
    36     
    37     private func unMark(_ n: Int, _ row: Int, _ column: Int, _ usedColumn: inout [Bool], _ usedDiagonals: inout [Bool], _ usedRevDiagonals: inout [Bool]) {
    38         usedColumn[column] = false
    39         usedDiagonals[row + column] = false
    40         usedRevDiagonals[row - column + n - 1] = false
    41     }
    42     
    43     
    44     private func isValid(_ n: Int, _ row: Int, _ column: Int, _ usedColumn: [Bool], _ usedDiagonals: [Bool], _ usedRevDiagonals: [Bool]) -> Bool {
    45         return !usedColumn[column] && !usedDiagonals[row + column] && !usedRevDiagonals[row - column + n - 1]
    46     }
    47     
    48     
    49     private func toList(_ n: Int, _ curr: [Int]) -> [String] {
    50         var res = [String]()
    51         for num in curr {
    52             var tmp = Array(repeating: ".", count: n)
    53             tmp[num] = "Q"
    54             var string = String()
    55             for s in tmp {
    56                 string += s
    57             }
    58             res.append(string)
    59         }
    60         return res
    61     }
    62 }

    68ms

     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         var board = [[Character]](repeating: [Character](repeating: ".", count: n), count: n)
     4         var result = [[String]]()
     5         backtrack(&board, 0, &result)
     6         return result
     7     }
     8     
     9     private func backtrack(_ board: inout [[Character]], _ row: Int, _ result: inout [[String]]) {
    10         if row == board.count {
    11             result.append(board.map { String($0) })
    12         } else {
    13             for col in 0..<board.count where canPlaceQueen(board, row, col) {
    14                 board[row][col] = "Q"
    15                 backtrack(&board, row + 1, &result)
    16                 board[row][col] = "."
    17             }
    18         }
    19     }
    20     
    21     private func canPlaceQueen(_ board: [[Character]], _ row: Int, _ col: Int) -> Bool {
    22         let n = board.count
    23         
    24         for i in 0..<row where board[i][col] == "Q" {
    25             return false
    26         }
    27         
    28         var i = row - 1
    29         var j = col - 1
    30         while i >= 0 && j >= 0 {
    31             if board[i][j] == "Q" {
    32                 return false
    33             }
    34             i -= 1
    35             j -= 1
    36         }
    37         
    38         i = row - 1
    39         j = col + 1
    40         while i >= 0 && j < n {
    41             if board[i][j] == "Q" {
    42                 return false
    43             }
    44             i -= 1
    45             j += 1
    46         }
    47         
    48         return true
    49     }
    50 }

    224ms

     1 class Solution {
     2     func solveNQueens(_ n: Int) -> [[String]] {
     3         var result = [[String]]()
     4         var currB = Array(repeating:String(Array(repeating:".",count:n)),count:n)
     5     
     6         helper(&result,&currB,n,0)
     7         return result
     8     }
     9     
    10     func canPlace( _ row: Int,  _ col: Int, _ board: [String]) -> Bool {
    11         var c = -1
    12         for i in 0..<row {
    13             for j in 0..<board[0].characters.count {
    14                 if charAt(board[i], j) == "Q" {
    15                     c = j
    16                     break
    17                 }
    18             }
    19             
    20             // check col
    21             if c == col {
    22                 return false
    23             }
    24             
    25             // check diagnol
    26             if abs(c - col) == abs(i - row) {
    27                 return false
    28             }
    29         }
    30         
    31         return true
    32     }
    33     
    34     func charAt(_ str: String, _ index: Int) -> Character {
    35         return str[str.index(str.startIndex, offsetBy: index)]
    36     }
    37     
    38     
    39     func helper(_ result: inout [[String]], _ currB: inout [String], _ n: Int, _ row: Int) {
    40     
    41         if(row>=n) {
    42             var curr = currB
    43             result.append(curr)
    44             return
    45         }
    46 
    47         for col in 0..<n {
    48             if(canPlace(row,col,currB)) {
    49                 //print("Placing Q at row:",row,"col:",col)
    50                 currB[row] = String(currB[row].prefix(col)) + String("Q") + String(currB[row].dropFirst(col + 1))
    51                 helper(&result,&currB,n,row+1)                
    52                 //Backtrack
    53                 currB[row] = String(currB[row].prefix(col)) + String(".") + String(currB[row].dropFirst(col + 1))
    54             }
    55             
    56         }
    57     
    58         return 
    59     }
    60 }
    
    
  • 相关阅读:
    freemarker模板引擎 常用标签
    SSH面试题
    JAVA 2013面试题-下
    JAVA 2013面试题-上
    String和StringBuffer
    http请求和http响应详细解析
    一种将汉字转换为拼音的更简单的方法
    中文字符串排序
    UIControl类控件统一管理
    日期转换
  • 原文地址:https://www.cnblogs.com/strengthen/p/9910395.html
Copyright © 2020-2023  润新知