力扣1222. 可以攻击国王的皇后

力扣1222. 可以攻击国王的皇后

题目描述

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

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

示例

在这里插入图片描述

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

解法:枚举

思路

对每个皇后进行遍历,判断是否在八个方向上。
如果在同一行上,横坐标相等;

queen[0] == king[0]

如果在同一列上,纵坐标相等;

queen[1] == king[1]

如果在同一对角线上,横坐标之差与纵坐标之差相等。

abs(king[0] - queen[0]) == abs(king[1] - queen[1])

因为同个方向上较远皇后的攻击会被最近皇后阻挡,因此对每个方向要取距离最近的皇后。为满足上述要求,定义一个以方向为key的哈希表,存储每个方向最近的皇后,以及她到国王的距离。

unordered_map<int, pair<vector<int>, int>> candidates;
//求出方向
int sx = sign(dx), sy = sign(dy);
//key代表方向的哈希映射
//为什么sx后面要乘上一个数?因为要放大哈希映射之间的距离,否则可能映射到同一个值
int key = sx*4 + sy;
int distance = abs(dx)+abs(dy);
//如果当前方向没有皇后直接放入,否则判断当前皇后的距离是否比哈希表里皇后更近
if(!candidates.count(key) || candidates[key].second > distance)
	candidates[key] = {queens[i], distance};    

完整代码

    int sign(int x)
    {
        //x大于0返回1,否则判断x是否等于0,等于0时返回0,否则返回-1
        return x>0?1:(x==0?0:-1);
    }
    vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
        int len = queens.size();

        unordered_map<int, pair<vector<int>, int>> candidates;
        int kx = king[0], ky = king[1];
        for(int i=0; i<len; i++)
        {
            int qx = queens[i][0], qy = queens[i][1];
            int dx = kx-qx, dy = ky - qy;
            //同行    //同列    //同对角线
            if(dx==0 || dy==0 || abs(dx)==abs(dy))
            {
                //求出方向
                int sx = sign(dx), sy = sign(dy);
                //key代表方向的哈希映射
                //为什么sx后面要乘上一个数?因为要放大哈希映射之间的距离,否则可能映射到同一个值
                int key = sx*4 + sy;
                int distance = abs(dx)+abs(dy);
                //如果当前方向没有皇后直接放入,对每个方向保留距离更近的皇后,较远皇后的攻击会被阻挡
                //firsrt和second是pair的属性,first代表前面的vector即最近的queen,second代表后面的int也就是distance
                if(!candidates.count(key) || candidates[key].second > distance)
                    candidates[key] = {queens[i], distance} ;    
            }
        }

        vector<vector<int>>ans;
        for(auto [_, value]:candidates)
            ans.push_back(value.first);

        return ans;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值