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

可以攻击国王的皇后

题目

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

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

示例 1:

复制代码
输入: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] 的皇后无法攻击到国王,因为她和国王不在同一行/列/对角线上。

示例 2:

复制代码
输入:queens = [[0,0],[1,1],[2,2],[3,4],[3,5],[4,4],[4,5]], king = [3,3]
输出:[[2,2],[3,4],[4,4]]

示例 3:

复制代码
输入: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]]

巧妙题解

::: tip

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

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

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

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

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

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

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

:::

代码 | 二维数组控制方向

js 复制代码
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;
};

代码 | 双层循环控制方向

js 复制代码
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;
};
相关推荐
猩兵哥哥10 分钟前
前端面向对象设计原则运用 - 策略模式
前端·javascript·vue.js
江城开朗的豌豆27 分钟前
解密React虚拟DOM:我的高效渲染秘诀 🚀
前端·javascript·react.js
江城开朗的豌豆43 分钟前
React应用优化指南:让我的项目性能“起飞”✨
前端·javascript·react.js
Asort1 小时前
JavaScript 从零开始(六):控制流语句详解——让代码拥有决策与重复能力
前端·javascript
EMT1 小时前
在 Vue 项目中使用 URL Query 保存和恢复搜索条件
javascript·vue.js
艾小码1 小时前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
前端康师傅2 小时前
JavaScript 作用域常见问题及解决方案
前端·javascript
CoovallyAIHub2 小时前
港大&字节重磅发布DanceGRPO:突破视觉生成RLHF瓶颈,多项任务性能提升超180%!
深度学习·算法·计算机视觉
Mintopia2 小时前
🚀 Next.js 全栈 E2E 测试:Playwright vs Cypress
前端·javascript·next.js
原生高钙2 小时前
JS设计模式指南
前端·javascript