publicclassSolution { public IList<IList<int>> QueensAttacktheKing(int[][] queens, int[] king) { ISet<int> queenPos = new HashSet<int>(); foreach (int[] queen in queens) { int x = queen[0], y = queen[1]; queenPos.Add(x * 8 + y); }
IList<IList<int>> ans = new List<IList<int>>(); for (int dx = -1; dx <= 1; ++dx) { for (int dy = -1; dy <= 1; ++dy) { if (dx == 0 && dy == 0) { continue; } int kx = king[0] + dx, ky = king[1] + dy; while (kx >= 0 && kx < 8 && ky >= 0 && ky < 8) { int pos = kx * 8 + ky; if (queenPos.Contains(pos)) { IList<int> posList = new List<int>(); posList.Add(kx); posList.Add(ky); ans.Add(posList); break; } kx += dx; ky += dy; } } } return ans; } }
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defqueensAttacktheKing(self, queens: List[List[int]], king: List[int]) -> List[List[int]]: queen_pos = set((x, y) for x, y in queens)
ans = list() for dx in [-1, 0, 1]: for dy in [-1, 0, 1]: if dx == dy == 0: continue kx, ky = king[0] + dx, king[1] + dy while0 <= kx < 8and0 <= ky < 8: if (kx, ky) in queen_pos: ans.append([kx, ky]) break kx += dx ky += dy return ans
int** queensAttacktheKing(int** queens, int queensSize, int* queensColSize, int* king, int kingSize, int* returnSize, int** returnColumnSizes) { HashItem *queen_pos = NULL; for (int i = 0; i < queensSize; i++) { int x = queens[i][0], y = queens[i][1]; hashAddItem(&queen_pos, x * 8 + y); }
int **ans = (int **)malloc(sizeof(int *) * queensSize); int curr_pos = 0; for (int dx = -1; dx <= 1; ++dx) { for (int dy = -1; dy <= 1; ++dy) { if (dx == 0 && dy == 0) { continue; } int kx = king[0] + dx, ky = king[1] + dy; while (kx >= 0 && kx < 8 && ky >= 0 && ky < 8) { int pos = kx * 8 + ky; if (hashFindItem(&queen_pos, pos)) { ans[curr_pos] = (int *)malloc(sizeof(int) * 2); ans[curr_pos][0] = kx; ans[curr_pos][1] = ky; curr_pos++; break; } kx += dx; ky += dy; } } } *returnColumnSizes = (int *)malloc(sizeof(int) * curr_pos); for (int i = 0; i < curr_pos; i++) { (*returnColumnSizes)[i] = 2; } *returnSize = curr_pos; hashFree(&queen_pos); return ans; }
funcqueensAttacktheKing(queens [][]int, king []int) [][]int { queen_pos := make(map[int]bool) for _, queen := range queens { x, y := queen[0], queen[1] queen_pos[x * 8 + y] = true } ans := [][]int{} for dx := -1; dx <= 1; dx++ { for dy := -1; dy <= 1; dy++ { if dx == 0 && dy == 0 { continue } kx, ky := king[0] + dx, king[1] + dy for kx >= 0 && kx < 8 && ky >= 0 && ky < 8 { pos := kx * 8 + ky if _, ok := queen_pos[pos]; ok { ans = append(ans, []int{kx, ky}) break } kx += dx ky += dy } } } return ans }
var queensAttacktheKing = function(queens, king) { queen_pos = newSet(); for (const queen of queens) { let x = queen[0], y = queen[1]; queen_pos.add(x * 8 + y); }
const ans = []; for (let dx = -1; dx <= 1; ++dx) { for (let dy = -1; dy <= 1; ++dy) { if (dx == 0 && dy == 0) { continue; } let kx = king[0] + dx, ky = king[1] + dy; while (kx >= 0 && kx < 8 && ky >= 0 && ky < 8) { let pos = kx * 8 + ky; if (queen_pos.has(pos)) { ans.push([kx, ky]); break; } kx += dx; ky += dy; } } } return ans; };
复杂度分析
时间复杂度:O(n + C),其中 n 是数组 queens 的长度,C 是棋盘的大小,在本题中 C = 8。我们需要 O(n) 的时间将所有皇后放入哈希表中,后续的枚举部分一共有 8 个方向,每两个对称的方向最多会遍历 C 个位置,因此一共最多遍历 4C = O(C) 个位置。
classSolution: defqueensAttacktheKing(self, queens: List[List[int]], king: List[int]) -> List[List[int]]: defsgn(x: int) -> int: return1if x > 0else (0if x == 0else -1) candidates = defaultdict(lambda: (None, inf)) kx, ky = king
for qx, qy in queens: x, y = qx - kx, qy - ky if x == 0or y == 0orabs(x) == abs(y): dx, dy = sgn(x), sgn(y) if candidates[(dx, dy)][1] > abs(x) + abs(y): candidates[(dx, dy)] = ([qx, qy], abs(x) + abs(y)) ans = [value[0] for value in candidates.values()] return ans