LeetCode 51.N皇后(JavaScript 解题)

简介: LeetCode 51.N皇后(JavaScript 解题)

LeetCode 51.N皇后

一、题目

1、问题描述

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

上图为 8 皇后问题的一种解法。

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

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

2、示例

输入:4

输出:[

[".Q…", // 解法 1

“…Q”,

“Q…”,

“…Q.”],

["…Q.", // 解法 2

“Q…”,

“…Q”,

“.Q…”]

]

3、提示

皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。

二、分析

该题为回溯算法的一道经典题目,解题思路如下。

1、构建空棋盘

for(let i = 0; i < n; i++){
    t.push(0);
}
for(let i = 0; i < n; i++){
    temp.push([...t]);//注意不能直接temp.push(t),直接赋值的话为浅拷贝,新数组只是原对象的一个引用
}

2、判断当前位置能否摆放

主要是在斜线上的判断,需要沿四个方向扩展出去。

//判断能否摆放
var judge = function(i,j,n){
    //横
    for(let k = 0;k < n; k++){
        if(temp[i][k] == 1) return 0;
    }
    //竖
    for(let k = 0;k < n; k++){
        if(temp[k][j] == 1) return 0;
    }
    //斜
    for(let k = 1; k + j < n && i - k >= 0; k++){
        if(temp[i - k][j + k] == 1) return 0;
    }
    for(let k = 1; k + i < n && j - k >= 0; k++){
        if(temp[i + k][j - k] == 1) return 0;
    }
    for(let k = 1; k + i < n && j + k < n; k++){
        if(temp[i + k][j + k] == 1) return 0;
    }
    for(let k = 1; i - k >= 0 && j - k >= 0; k++){
        if(temp[i - k][j - k] == 1) return 0;
    }
    return 1;
}

3、深搜回溯

//深搜遍历
var dfs = function(e,n){
    //遍历当前行的每一列
    for(let i = 0;i < n; i++){
        //判断能否摆放
        if(temp[e][i] == 0 && judge(e,i,n)){
            //标记当前位置已摆放
            temp[e][i] = 1;
            //已经摆置n个皇后
            if(e == n-1){
                var ans = [];
                for(let i1 = 0; i1 < n; i1++){
                    var a = "";
                    for(let i2 = 0; i2 < n; i2++){
                        //格式化输出
                        if(temp[i1][i2] == 0) a += ".";
                        else a += "Q";
                    }
                    ans.push(a);
                }
                //将当前结果放进列表
                res.push(ans);
            }else{
                //没够n个,继续往下遍历
                dfs(e+1,n);
            }
        }
        //回溯,取消标记
        temp[e][i] = 0;
    }
}

三、代码

/**
 * @param {number} n
 * @return {string[][]}
 */
var solveNQueens = function(n) {
    var t = [],
        temp = [],
        res = [];
    for(let i = 0; i < n; i++){
        t.push(0);
    }
    for(let i = 0; i < n; i++){
        temp.push([...t]);
    }
    //判断能否摆放
    var judge = function(i,j,n){
        //横
        for(let k = 0;k < n; k++){
            if(temp[i][k] == 1) return 0;
        }
        //竖
        for(let k = 0;k < n; k++){
            if(temp[k][j] == 1) return 0;
        }
        //斜
        for(let k = 1; k + j < n && i - k >= 0; k++){
            if(temp[i - k][j + k] == 1) return 0;
        }
        for(let k = 1; k + i < n && j - k >= 0; k++){
            if(temp[i + k][j - k] == 1) return 0;
        }
        for(let k = 1; k + i < n && j + k < n; k++){
            if(temp[i + k][j + k] == 1) return 0;
        }
        for(let k = 1; i - k >= 0 && j - k >= 0; k++){
            if(temp[i - k][j - k] == 1) return 0;
        }
        return 1;
    }
    //深搜遍历
    var dfs = function(e,n){
        for(let i = 0;i < n; i++){
            if(temp[e][i] == 0 && judge(e,i,n)){
                temp[e][i] = 1;
                if(e == n-1){
                    var ans = [];
                    for(let i1 = 0; i1 < n; i1++){
                        var a = "";
                        for(let i2 = 0; i2 < n; i2++){
                            if(temp[i1][i2] == 0) a += ".";
                            else a += "Q";
                        }
                        ans.push(a);
                    }
                    res.push(ans);
                }else{
                    dfs(e+1,n);
                }
            }
            temp[e][i] = 0;
        }
    }
    dfs(0,n);
    return res;
};

四、个人博客

个人博客地址

目录
相关文章
|
2月前
|
人工智能 自然语言处理 程序员
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
欢迎来到工程师令狐小哥的频道。本文介绍如何利用AI工具高效刷LeetCode,通过通义灵码插件在IntelliJ IDEA中实现代码生成、优化、单元测试等功能,提升编程学习效率。
91 1
通义灵码:融合创新玩法与探索,重塑LeetCode解题策略
|
6月前
|
存储 JavaScript 前端开发
【经典算法】LeetCode350:两个数组的交集 II(Java/C/Python3/JavaScript实现含注释说明,Easy)
【经典算法】LeetCode350:两个数组的交集 II(Java/C/Python3/JavaScript实现含注释说明,Easy)
33 1
【力扣-TS解题】1、回文数
【力扣-TS解题】1、回文数
53 0
|
JavaScript 前端开发
leetcode 1418.点菜展示表(JavaScript)
leetcode 1418.点菜展示表(JavaScript)
44 0
|
JavaScript 前端开发 算法
LeetCode 37.解数独(注释完整+JavaScript解题)
LeetCode 37.解数独(注释完整+JavaScript解题)
88 0
|
JavaScript 前端开发
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
|
JavaScript 前端开发
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
【LeetCode】JavaScript题解:电话号码的字母组合|组合总和Ⅲ
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
63 6
|
4月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
125 2