https://leetcode.cn/problems/queens-that-can-attack-the-king/description/
在一个 8x8 的棋盘上,放置着若干「黑皇后」和一个「白国王」。
给定一个由整数坐标组成的数组
queens,表示黑皇后的位置;以及一对坐标king,表示白国王的位置,返回所有可以攻击国王的皇后的坐标(任意顺序)。示例 1:
1
2
3
4
5
6
7
8
9 输入: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:
1
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:
1
2 输入: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 <= queens.length <= 63queens[i].length == 20 <= queens[i][j] < 8king.length == 20 <= king[0], king[1] < 8- 一个棋盘格上最多只能放置一枚棋子。
方法一:遍历王后,查找可以攻击到国王的位置
王后可以攻击到国王的情况:
- 国王在王后的攻击范围内,即横、竖、交叉线四线中
- 国王与王后之间没有其他棋子
所以,要解决这个问题,首先需要判断国王是否在王后的攻击范围
- 在横竖直线上表示两点横坐标或纵坐标相同,即
queen[x] - king[x] == 0或queen[y] - king[y] == y,简化则是(queen[x] - king[x]) * (queen[y] - king[y]) == 0 - 在交叉斜线上则有
|queen[x] - king[x]| == |queen[y] - king[y]|
当判断出可以攻击之后,下一步就要判断国王与王后之前是否有其他棋子
- 我们首先定义一个二维数组表示棋盘,遍历王后将王后置于棋盘上
- 由于两点可确定一条直线,即由国王与王后间构成的一条直线
- 从两点中横坐标较小的一侧出发,通过直线方程计算出纵坐标,再通过棋盘查找该点是否有棋子
1 | class Solution { |
方法二:统计能被国王「看到」的皇后(by 灵茶山艾府)
能攻击到国王的皇后,需要满足:
皇后与国王在同一行,或者同一列,或者同一斜线。
皇后与国王之间没有棋子。换句话说,皇后不能被其它皇后挡住。
一种思路是枚举每个皇后,去判断是否满足上述条件。
更加巧妙的做法是,站在国王的视角,计算有哪些皇后能被国王「看到」。
想象成从国王的位置发射八个方向的射线,记录每条射线首次遇到的皇后。
1 | class Solution { |


