LeetCode算法学习之--递归--51.N皇后

121 阅读2分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

大家好今天给大家分享下一道 LeetCode 困难度 的题目51. N 皇后

题目

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

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

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

image.png (来自LEETCODE)

分析

1.皇后可以横着走, 所以在没一个row 上面只能有一个Q

2.皇后可以竖着走, 所以在没一个column 上面只能有一个Q

3.皇后可以两个交叉的对角线上走着走, 所以在2个交叉的对角线上 diagonal上只能有一个Q

4.把找到的答案,放在一个nn的棋盘上, “.”代表空,“Q”代表皇后*

5.把所有的代码放入一数组中,并且返回

解法

递归

递归

思路
1.每行使用row 来代替,每列使用column来代替
2. 通过观察我们可以发现 左上角到右下角的对角线的 通过公式表单等于 (横坐标-纵坐标===一个固定的值)
3. 相似的 左下角到右上角的对角线的 通过公式表单等于 (横坐标+纵坐标===一个固定的值)
4. 于是我们就通过递归的方式,遇到有在 行 列 对角线上重叠的 我们跳过当前循环
5.最后如果row ===n 那么说明已经找到一组合适的答案, 然后生成棋盘,放入solutions中
*/
​
var solveNQueens = function (n) {
  // 初始答案合集
  const solutions = [];
  //   记录皇后在每行中的位置
  const queens = [];
  //   记录列
  const columns = [];
  //   记录左上角到右下角的对角线的
  const diagonal1 = [];
  //   左下角到右上角的对角线
  const diagonal2 = [];
​
  //   递归
  function recur(row, queens, columns, diagonal1, diagonal2) {
    for (let i = 0; i < n; i++) {
      // 如果row ===n 那么说明已经找到一组合适的答案, 然后生成棋盘,放入solutions中
      if (row === n) {
        const solution = generateBoard(queens);
        solutions.push(solution);
        return;
      }
​
      //   如果在列上有重叠则跳过当前迭代
      if (columns.includes(i)) continue;
      //   如果两个对角线上有重叠则跳过当前迭代
      if (diagonal1.includes(row - i)) continue;
      if (diagonal2.includes(row + i)) continue;
​
      //   row+1 进行寻找下一行 Qeen的合适位置
      /*  注意这里的queens colunms diagonal1 diagonal2 都必须返回新的数组,因为JS中数组是对象都是使用的指针,
      这样会改变原始内存地址的值产生副作用 会影响下一个迭代的递归运算 */
      recur(
        row + 1,
        [...queens, i],
        [...columns, i],
        [...diagonal1, row - i],
        [...diagonal2, row + i]
      );
    }
  }
​
  //   刚开始row 为0
  recur(0, queens, columns, diagonal1, diagonal2);
​
  //   生成棋盘
  function generateBoard(queens) {
    const solution = [];
    for (let i = 0; i < n; i++) {
      const board = new Array(n).fill(".");
      //   因为queens里面是记录没行queen的位置,所以board[queens[i]]  就表示在i行中,Q应该放那个位置
      board[queens[i]] = "Q";
      solution.push(board.join(""));
    }
​
    return solution;
  }
​
  return solutions;
};
​
/* 复杂度
时间 O(n*n!)
空间 O(n)
*/

总结

今天这道题是主要是练习使用递归来求解生成组合的这类题目

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com