• 可以攻击国王的皇后(JS)


    可以攻击国王的皇后

    题目

    在一个 8x8 的棋盘上,放置着若干「黑皇后」和一个「白国王」。

    给定一个由整数坐标组成的数组 queens ,表示黑皇后的位置;以及一对坐标 king ,表示白国王的位置,返回所有可以攻击国王的皇后的坐标(任意顺序)。

    示例 1:

    img

    输入:queens = [[0,1],[1,0],[4,0],[0,4],[3,3],[2,4]], king = [0,0]
    输出:[[0,1],[1,0],[3,3]]
    解释: 
    [0,1] 的皇后可以攻击到国王,因为他们在同一行上。 
    [1,0] 的皇后可以攻击到国王,因为他们在同一列上。 
    [3,3] 的皇后可以攻击到国王,因为他们在同一条对角线上。 
    [0,4] 的皇后无法攻击到国王,因为她被位于 [0,1] 的皇后挡住了。 
    [4,0] 的皇后无法攻击到国王,因为她被位于 [1,0] 的皇后挡住了。 
    [2,4] 的皇后无法攻击到国王,因为她和国王不在同一行/列/对角线上。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例 2:

    img

    输入:queens = [[0,0],[1,1],[2,2],[3,4],[3,5],[4,4],[4,5]], king = [3,3]
    输出:[[2,2],[3,4],[4,4]]
    
    • 1
    • 2

    示例 3:

    img

    输入:queens = [[5,6],[7,7],[2,1],[0,7],[1,6],[5,1],[3,7],[0,3],[4,0],[1,2],[6,3],[5,0],[0,4],[2,2],[1,1],[6,4],[5,4],[0,0],[2,6],[4,5],[5,2],[1,4],[7,5],[2,3],[0,5],[4,2],[1,0],[2,7],[0,1],[4,6],[6,1],[0,6],[4,3],[1,7]], king = [3,4]
    输出:[[2,3],[1,4],[1,6],[3,7],[4,3],[5,4],[4,5]]
    
    • 1
    • 2

    巧妙题解

    ::: tip

    分析:本题要求找到以国王位置处发散的每一条路径上的第一个皇后。

    能攻击到国王的皇后,需要满足:

    1. 与国王在同一水平,竖直或者斜线方向的的皇后。
    2. 结果只取每条路径上的第一给皇后。

    一种思路是枚举每个皇后,去判断是否满足上述条件。

    更加巧妙的做法是,站在国王的视角,计算有哪些皇后能被国王「看到」。

    想象成从国王的位置发射八个方向的射线,记录每条射线首次遇到的皇后。

    这个思路很简单但是如何实现是一个考验编程能力的事情。

    :::

    代码 | 二维数组控制方向

    var queensAttacktheKing = function(queens, king) {
        //这里将要以整个棋盘创建二维数组,其中皇后位置为true,初始化时全部置为false;
        let isQueen = new Array(8).fill(null).map(()=>new Array(8).fill(false));
        for(let [x,y] of queens){
            isQueen[x][y] = true;
        }
        //创建一个记录结果的数组;
        let res = [];
        //这里表示8个方向,表示以国王为原点,在二维坐标系的八个方向
        let direction  = [[1,0],[1,1],[0,1],[-1,1],[-1,0],[-1,-1],[0,-1],[1,-1]];
        //外循环控制方向,每一个方向遍历到遇到皇后或者结束为止
        for(const [dx,dy] of direction){
            let x = king[0] + dx;
            let y = king[1] + dy;
            while(x>=0&&x<8&&y>=0&&y<8){
                if(isQueen[x][y]){
                    //第一次在这个方向上遇到皇后,记录其位置并结束循环
                    res.push([x,y]);
                    break;
                }
                //如果没有到循环结束条件,那么遍历将继续在这个方向上继续下去
                x+=dx;
                y+=dy;
            }
        }
        return res;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    代码 | 双层循环控制方向

    ar queensAttacktheKing = function(queens, king) {
        //这里将要以整个棋盘创建二维数组,其中皇后位置为true,初始化时全部置为false;
        let isQueen = new Set();
        for(let [x,y] of queens) isQueen.add(x*8 + y);//存下的每一个皇后位置都有自己位置独特的值
        //创建一个记录结果的数组;
        let res = [];
        //这里循环八个方向,进行遍历查找
        for(let dx = -1;dx <= 1; dx++){
            for(let dy = -1;dy <= 1; dy++){
                if(dx==0&&dy==0) continue;
                let x = king[0] + dx;
                let y = king[1] + dy;
                while(x>=0&&x<8&&y>=0&&y<8){
                    let pos  = x*8 + y;
                    if(isQueen.has(pos)){
                        //第一次在这个方向上遇到皇后,记录其位置并结束循环
                        res.push([x,y]);
                        break;
                    }
                    //如果没有到循环结束条件,那么遍历将继续在这个方向上继续下去
                    x+=dx;
                    y+=dy;
                }
            }
        }
        return res;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    Atcoder Beginner Contest 273E - Notebook 解题报告
    Erasure-Code-擦除码-2-实现篇
    JS中执行上下文和执行栈是什么?
    我在国企当合同工的那段日子
    PostgreSQL设置主键为自增
    Linux操作系统:字符串处理及awk与sed
    5.Nacos
    Flutter 3.16 中带来的更新
    LeetCode 周赛上分之旅 #49 再探内向基环树
    Spring Boot 集成 EasyExcel 3.x
  • 原文地址:https://blog.csdn.net/weixin_63050915/article/details/133205872