题目链接:leetcode-cn.com/problems/qu…
枚举白国王8个方向,遇到每个方向上第一个的黑的黑皇后即为解
未优化前:
class Solution {
// 八个方向
private int [][] action = new int[][]{{-1,0},{1,0},{0,1},{0,-1},{1,-1},{1,1},{-1,1},{-1,-1}};
public List<List<Integer>> queensAttacktheKing(int[][] queens, int[] king) {
List<List<Integer>> result = new ArrayList<>();
Map<Integer, Set<Integer>> find = new HashMap<>();
for (int[] queen : queens) {
Set<Integer> set = find.getOrDefault(queen[0], new HashSet<>());
set.add(queen[1]);
find.put(queen[0], set);
}
int kingX = king[0];
int kingY = king[1];
for (int[] ints : action) {
int newX = kingX;
int newY = kingY;
while (canGo(newX, newY)) {
if (find.containsKey(newX) && find.get(newX).contains(newY)) {
List<Integer> pos = new ArrayList<>(Arrays.asList(newX, newY));
result.add(pos);
break;
}
newX = newX + ints[0];
newY = newY + ints[1];
}
}
return result;
}
private boolean canGo(int x, int y){
return x>=0 && y>=0 && x<8 && y<8;
}
}
使用boolean数组代替复杂嵌套的HashMap,优化后:
class Solution {
public List<List<Integer>> queensAttacktheKing(int[][] queens, int[] king) {
boolean[][] falgs = new boolean[8][8];
List<List<Integer>> res = new LinkedList<>();
for(int[] queen:queens){
falgs[queen[0]][queen[1]]=true;
}
int[][] font = {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
for (int i = 0; i < font.length; i++) {
for (int x=king[0],y=king[1];canGo(x, y);x+=font[i][0],y+=font[i][1]) {
// 判断是否黑皇后
if(falgs[x][y]){
res.add(Arrays.asList(x,y));
break;
}
}
}
return res;
}
// 判断是否符合边界条件
private boolean canGo(int x, int y){
return x>=0&&x<8&&y<8&&y>=0;
}
}
收获:
1.使用横、纵坐标的运算方式作为方向的映射,避免了使用switch和if的判断。
2.尽量使用基本类型的数组代替集合类