「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
大家好今天给大家分享下一道 LeetCode 困难度 的题目51. N 皇后
题目
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位
(来自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