算法题:N 皇后

leetcode 地址:N 皇后


好几天没更新了,一是确实被这题卡住了,二是最近上线的东西有点多。

思路

采用 DFS 遍历的方式,先按一路往下冲,当某行没有位置可放的时候,再调整下上一行的皇后位置,继续往下冲。

这道题我觉得有 3 个关键点:

  1. 找出限制条件,也就是每放一个皇后,哪些地方是不能再放了。经过分析可以看到,一个皇后会控制三个方向,我们称之为列、撇、捺。
  2. 限制条件的传递,每一行得记住当前行的限制条件(就是从上一层传下来的)。当你在同一行移动列位置的时候,限制条件是不变的。我当时栽过一个坑就是同一行列移动时,把限制条件给改变了。
  3. 记录限制条件,不要用数组,可以用 Map 一类的。因为在计算“捺”的时候,是横竖坐标相减,这时候会出现负数的情况(比如你用行减列,碰到 ( 0 , 1 ) (0,1) (01) 就变负数了)。

代码

➥ JavaScript

/**
 * @param {number} n
 * @return {string[][]}
 */
var solveNQueens = function (n) {
  if (n === 1) return [['Q']]
  if (n < 4) return []

  const result = []
  let solution = []
  const cols = new Map() // 限制条件:列
  const pie = new Map() // 限制条件:撇
  const na = new Map() // 限制条件:捺

  const dfs = (row) => {
    if (row >= n) {
      result.push(solution.concat([]))
      return
    }

    for (let col = 0; col < n; col++) {
      if (row === 0) {
        solution = []
      }

      if (cols.get(col) || pie.get(row + col) || na.get(col - row)) {
        // 三大限制条件满足一个,该位置就不能放
      } else {
      	// 每一个皇后会更新三大限制条件
        cols.set(col, 1)
        pie.set(row + col, 1)
        na.set(col - row, 1)
        const hang = new Array(n).fill('.')
        hang[col] = 'Q'
        solution[row] = hang.join('')
        dfs(row + 1)
        // 还原行的限制条件
        cols.delete(col)
        pie.delete(row + col)
        na.delete(col - row)
      }
    }
  }

  dfs(0)

  return result
};

这个解决我在 leetcode 上跑了下,时间和空间复杂度都不高。也看了一些高手的解法,有些 Python 高手将代码写的很简洁,但确实很难读懂,而且思路貌似也殊途同归。

我觉得做算法首先用普通人的思维能解出来就好,等熟练了再去想些极致的办法。就好比面试的时候,如果面试者能说出最佳解法,而不能一下子说出本办法,那心里其实是要有个疑问的 —— 真这么厉害,还是背题的?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值