力扣: 可以攻击国王的皇后

题目描述


在一个 8x8 的棋盘上,放置着若干「黑皇后」和一个「白国王」。
「黑皇后」在棋盘上的位置分布用整数坐标数组 queens 表示,「白国王」的坐标用数组 king 表示。
「黑皇后」的行棋规定是:横、直、斜都可以走,步数不受限制,但是,不能越子行棋。
请你返回可以直接攻击到「白国王」的所有「黑皇后」的坐标(任意顺序)。
力扣:1222.可以攻击国王的皇后

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

在这里插入图片描述
题目分析:
题目意思还是很容易理解的,但可能第一时间会被题目误导,想到 从皇后Q 出发,判断是否能直接攻击到 国王K , 国王嘛 (懂得都懂) ,皇后可能会很多,如果挨个判断不仅耗时还麻烦,逆向思考,会发现 国王能直接攻击的皇后 ,和皇后能直接攻击国王,是等价的问题 ,毕竟国王只有一个。
因此只要考虑 国王在八个方向上能直接攻击到的皇后 问题即可解决。

考虑到皇后是通过一个二维数组来存储坐标,如果每次移动都需要比对二维数组,处理起来相对麻烦,因此可以先将棋盘还原出来,把相应的坐标位置设置为 Q ,那么每次只需要判断格子的内容是否为 Q 即可。

char[][] chess = new char[8][8];
for(int i = 0 ; i < 8 ; i ++)
    for(int j = 0 ; j < 8 ; j ++)
        chess[i][j] = '.';
for(int[] black : queens)
    chess[black[0]][black[1]] = 'Q';

棋盘已经构建完成,但 国王有八个方向需要判断 ,不可能每个方向用一个 for 循环解决 ,方向处理如下:

 // 定义 8 个方向
 int[] dr = {-1 , 1 , 0 , 0 , -1 , -1 , 1 , 1}; // 上 下 左 右 左上 右上 左下 右下
 int[] dc = {0 , 0 , -1 , 1 , -1 , 1 , -1 , 1};
 for(int i = 0 ; i < 8 ; i ++){
     for(int r = row , c = col ; r >= 0 && r < 8 && c >= 0 && c < 8 ; r += dr[i] , c += dc[i]){
  		if(chess[r][c] == 'Q'){
             result.add(Arrays.asList(r , c));
             break;
         }
     }
 }

完整代码:

class Solution {
    public List<List<Integer>> queensAttacktheKing(int[][] queens, int[] king) {
		// 还原棋盘
        char[][] chess = new char[8][8];
        for(int i = 0 ; i < 8 ; i ++)
            for(int j = 0 ; j < 8 ; j ++)
                chess[i][j] = '.';
        for(int[] black : queens)
            chess[black[0]][black[1]] = 'Q';

        List<List<Integer>> result = new ArrayList<>();
        solve(result , chess , king[0] , king[1]);
        return result;
        
    }

    // 只需要对 K 的 8 个方向进行判断,每个方向上第一个遇到的 Q 存入 结果集中
    void solve(List<List<Integer>> result , char[][] chess , int row , int col){
        
        // 8 个方向
        int[] dr = {-1 , 1 , 0 , 0 , -1 , -1 , 1 , 1}; // 上 下 左 右 左上 右上 左下 右下
        int[] dc = {0 , 0 , -1 , 1 , -1 , 1 , -1 , 1};

        for(int i = 0 ; i < 8 ; i ++){
            for(int r = row , c = col ; r >= 0 && r < 8 && c >= 0 && c < 8 ; r += dr[i] , c += dc[i])
                if(chess[r][c] == 'Q'){
                    result.add(Arrays.asList(r , c));
                    break;
                }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值