题目描述
在一个 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] 的皇后无法攻击到国王,因为她和国王不在同一行/列/对角线上。
输入:queens = [[0,0],[1,1],[2,2],[3,4],[3,5],[4,4],[4,5]], king = [3,3]
输出:[[2,2],[3,4],[4,4]]
输入: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 <= 63
queens[0].length == 2
0 <= queens[i][j] < 8
king.length == 2
0 <= king[0], king[1] < 8
- 一个棋盘格上最多只能放置一枚棋子。
算法
(暴力枚举) $O(8 \times 8)$
- 把所有
Queen
放到哈希表中,然后枚举King
周围的八个方向,找到每个方向第一个Queen
的位置。
时间复杂度
- 8 个方向,每个方向最多有 8 个位置。
空间复杂度
- 需要额外的 8x8 的棋盘空间。
C++ 代码
class Solution {
public:
vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
vector<vector<bool>> c(8, vector<bool>(8, false));
for (const auto &q: queens)
c[q[0]][q[1]] = true;
const int dx[8] = {0, -1, -1, -1, 0, 1, 1, 1};
const int dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
vector<vector<int>> ans;
int x = king[0], y = king[1];
for (int d = 0; d < 8; d++) {
int i = x + dx[d], j = y + dy[d];
while (i >= 0 && i < 8 && j >= 0 && j < 8) {
if (c[i][j]) {
ans.push_back({i, j});
break;
}
i += dx[d]; j += dy[d];
}
}
return ans;
}
};
每周必看 ahhh