LC-51. N 皇后

170 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

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

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

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

示例 1:

image.png

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

示例 2:

输入: n = 1
输出: [["Q"]]

提示:

  • 1 <= n <= 9

题解

棋盘类问题可以通过回溯的方法来解决

注意攻击条件,可以先判断当前的值是否处于攻击状态,再push会好点。

如果先push,然后再判断,再pop,就会浪费执行速度。

回溯

const solveNQueens = (n) => {
  const res = []

  const isAttack = (x, y, arr) => {
    if (x === 0) return false

    for (let i = 0; i < x; i++) {
      const [row, column] = arr[i]

      if (y === column) return true

      if (Math.abs(row - x) === Math.abs(column - y)) return true
    }
    return false
  }

  const handleData = (arr) => {
    const valueArr = []
    for (let i = 0; i < n; i++) {
      let defaultArr = new Array(n).fill('.')
      const [row, column] = arr[i]
      defaultArr[column] = 'Q'
      valueArr.push(defaultArr.join(''))
    }
    return valueArr
  }

  // x,y为当前皇后位置
  // arr 用于存放每一行 皇后所在位置
  const search = (row, arr) => {
    if (row === n) {
      res.push(handleData(arr))
    }

    // 循环的是这一行上的数据,也就是每一列
    for (let column = 0; column < n; column++) {
      if (!isAttack(row, column, arr)) {
        arr.push([row, column])

        search(row + 1, arr)

        arr.pop([row, column])
      }
    }
  }

  search(0, [])

  return res
}

总结

题目 28 :这道题通过回溯的方法来解决,就是在最后字符串处理,感觉有点麻烦,看看后续有没有可以优化的。