On an 8x8 chessboard, there can be multiple Black Queens and one White King.
Given an array of integer coordinates queens
that represents the positions of the Black Queens, and a pair of coordinates king
that represent the position of the White King, return the coordinates of all the queens (in any order) that can attack the King.
Example 1:
Input: queens = [[0,1],[1,0],[4,0],[0,4],[3,3],[2,4]], king = [0,0]
Output: [[0,1],[1,0],[3,3]]
Explanation:
The queen at [0,1] can attack the king cause they're in the same row.
The queen at [1,0] can attack the king cause they're in the same column.
The queen at [3,3] can attack the king cause they're in the same diagnal.
The queen at [0,4] can't attack the king cause it's blocked by the queen at [0,1].
The queen at [4,0] can't attack the king cause it's blocked by the queen at [1,0].
The queen at [2,4] can't attack the king cause it's not in the same row/column/diagnal as the king.
Example 2:
Input: queens = [[0,0],[1,1],[2,2],[3,4],[3,5],[4,4],[4,5]], king = [3,3]
Output: [[2,2],[3,4],[4,4]]
Example 3:
Input: 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]
Output: [[2,3],[1,4],[1,6],[3,7],[4,3],[5,4],[4,5]]
Constraints:
1 <= queens.length <= 63
queens[i].length == 2
0 <= queens[i][j] < 8
king.length == 2
0 <= king[0], king[1] < 8
- At most one piece is allowed in a cell.
這道題說是在一個 8 by 8 大小的國際象棋的棋盤上,放了多個黑色皇后和一個白色的國王,國際象棋的中的皇后就相當於中國象棋中的車,不過比車更叼,不但能橫豎走,還能斜着走,國王就相當於將和帥,現在問有多少個皇后能攻擊到國王。題目中的每個例子都十分貼心的配了圖,可以更好的幫助我們理解。博主最開始沒看清楚題目,認為直接判斷每個皇后是否跟國王共線就可以了,但是即便是共線,也不代表皇后就可以攻擊到國王,若中間還有其他皇后就不行,就像例子1中的那樣。所以視角就應該轉移到國王本身,對於棋盤上任意一個非邊緣位置,共有八個方向可以去,而每個方向都可能遇到皇后,一旦遇到皇后了,這個方向就不會再遇到其他的皇后了。所以就應該以國王為起點,分別朝八個方向前進,看是否可以遇到皇后。
博主之前寫出的解法有點復雜,是分別遍歷八個方向的情況,但實際上可以寫的更加簡潔一些,利用方向變量的 offset,就像在迷宮遍歷時,寫出四個方向的變量一樣,這里八個方向其實就是 [-1, 0, 1] 中任取兩個數字分別加上當前的橫縱坐標,注意要去掉 (0, 0) 這種情況,因為並不會發生位置的變化。所以當拿到一組偏移量時,就可以進行 while 循環,條件時不越界,當新位置上有皇后時,將該位置加入結果 res,並 break 掉循環,否則再次加上偏移量繼續循環。如何快速的知道某個位置上是否有皇后呢,當然不能每次遍歷一次所有皇后的位置,太不高效,這里可以建立另一個 8 by 8 大小的二維數組 seen,當 seen[i][j] 為1時,就表示 (i, j) 位置是皇后,參見代碼如下:
class Solution {
public:
vector<vector<int>> queensAttacktheKing(vector<vector<int>>& queens, vector<int>& king) {
vector<vector<int>> res, seen(8, vector<int>(8));
for (auto queen : queens) {
seen[queen[0]][queen[1]] = 1;
}
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
if (i == 0 && j == 0) continue;
int x = king[0] + i, y = king[1] + j;
while (min(x, y) >= 0 && max(x, y) < 8) {
if (seen[x][y] == 1) {
res.push_back({x, y});
break;
}
x += i, y += j;
}
}
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1222
參考資料:
https://leetcode.com/problems/queens-that-can-attack-the-king/
https://leetcode.com/problems/queens-that-can-attack-the-king/discuss/403755/C%2B%2B-Tracing