日常生活的交流与学习

首页 新随笔 联系 管理
/**
 * @param {number} n
 * @return {string[][]}
 */

let solveNQueens = function (n) {
  let res = []
  // 已摆放皇后的的列下标
  let columns = []
  // 已摆放皇后的对角线1下标 左下 -> 右上
  // 计算某个坐标是否在这个对角线的方式是「行下标 + 列下标」是否相等
  let dia1 = []
  // 已摆放皇后的对角线2下标 左上 -> 右下
  // 计算某个坐标是否在这个对角线的方式是「行下标 - 列下标」是否相等
  let dia2 = []

  // 尝试在一个n皇后问题中 摆放第index行内的皇后位置
  let putQueen = (rowIndex, row) => {
    if (rowIndex === n) {
      // res.push(generateBoard(row))
      res.push(row)
      return
    }

    // 尝试摆第index行的皇后 尝试[0, n-1]列
    for (let columnIndex = 0; columnIndex < n; columnIndex++) {
      // 在列上不冲突
      let columnNotConflict = !columns[columnIndex]
      // 在对角线1上不冲突
      let dia1NotConflict = !dia1[rowIndex + columnIndex]
      // 在对角线2上不冲突
      let dia2NotConflict = !dia2[rowIndex - columnIndex]

      if (columnNotConflict && dia1NotConflict && dia2NotConflict) {
        columns[columnIndex] = true
        dia1[rowIndex + columnIndex] = true
        dia2[rowIndex - columnIndex] = true

        putQueen(rowIndex + 1, row.concat(columnIndex))

        columns[columnIndex] = false
        dia1[rowIndex + columnIndex] = false
        dia2[rowIndex - columnIndex] = false
      }
    }
  }

  putQueen(0, [])

  return res
}

function generateBoard(row) {
  let n = row.length
  let res = []

  // 每一行进行循环
  for (let y = 0; y < n; y++) {
    let cur = ""

    // 每一列进行循环
    for (let x = 0; x < n; x++) {
      // 分支结构
      // 分析for内部的逻辑结构需要注意的问题:
      // 1. 如果只是一层for循环,那么我们只需要关注哪些变量是不变的,哪些变量是经常变化的量,也就是用于循环的变量,
      //    这个变量经常变化,所以是我们的重点关注对象
      // 2. 如果两层for循环,那么变化的变量会有两个,越往里层for循环的变量,变化越明显,因此,我们在分析的需要
      //    先"按住"一个变量,然后据此进行分析内层for循环,分析好之后,在松开外层变量,进行下一轮循环分析
      if (x === row[y]) cur += "Q"
      else cur += "."
    }

    res.push(cur)
  }
  return res
}

console.log(solveNQueens(4))
posted on 2022-12-30 19:35  lazycookie  阅读(29)  评论(0编辑  收藏  举报