1222. 可以攻击国王的皇后

130 阅读1分钟

题目链接: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.尽量使用基本类型的数组代替集合类