【LeetCode练习】[困难]1001. 网格照明

【LeetCode练习】[困难]1001. 网格照明

1001. 网格照明

题目来源
算法思想:二维数组,回溯

题目:
在这里插入图片描述
照明覆盖情况分析:

  1. columns 行列长度范围: 0 到 n - 1
  2. diagonals1 正对角线范围 i - j : - ( n - 1 ) 到 n-1,
  3. diagonals2 反对角线范围 i + j : 0 到 2 * ( n - 1 ),
  4. 利用map存储,数组存储,内存爆了

详细说明如下图(参照皇后问题说明):
在这里插入图片描述

java代码

class Solution {
    private static final long MAX_NUM = 1000000000L;
    //初始化      
  	//rows 行长度范围: 0到n-1
  	//columns 列长度范围: 0到n-1
  	//diagonals1 正对角线范围i-j: -(n-1)到n-1,
  	//diagonals2 反对角线范围i+j: 0到2*(n-1)
    private Map<Integer, Integer> rows = new HashMap<Integer, Integer>();
    private Map<Integer, Integer> columns = new HashMap<Integer, Integer>();
    private Map<Integer, Integer> diagonals1 = new HashMap<Integer, Integer>();
    private Map<Integer, Integer> diagonals2 = new HashMap<Integer, Integer>();
    // 标记某些位置是否有灯,1000000000L * row + col
    private Set<Long> lampSet = new HashSet<>();

    private void setMymap(Map<Integer, Integer> map, int key) {
        if (map.containsKey(key)) {
            map.put(key, map.get(key) + 1);//如果存在数值++;
        } else {
            map.put(key, 1);//如果不存在,新加入,将值设置成1;
        }
    }

    private void minusMymap(Map<Integer, Integer> map, int key) {
    	if (map.get(key) > 1) {
    		map.put(key, map.get(key) - 1);
		}else {
			map.remove(key);
		}
    }

    //去掉row,col周围的灯
    private void closeNeighborLamp(int row, int col) {
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                int newRow = row + i;
                int newCol = col + j;
                if (newRow < 0 || newCol < 0) {
                    continue;
                }
                long lamp = MAX_NUM * newRow + newCol;
                if (lampSet.contains(lamp)) {//如果存在灯,进行灯照范围消除
                    lampSet.remove(lamp);//去掉灯
                    minusMymap(rows, newRow);//消除行
                    minusMymap(columns, newCol);//消除列
                    minusMymap(diagonals1, newRow - newCol);//消除正对角线
                    minusMymap(diagonals2, newRow + newCol);//消除反对角线
                }
            }
        }
    }

    public int[] gridIllumination(int N, int[][] lamps, int[][] queries) {
        int queryCount = queries.length;
        if (queryCount == 0) {
            return new int[]{};
        }

        for (int[] lamp : lamps) {//遍历灯
            int row = lamp[0];//行
            int col = lamp[1];//列
            int diagonal1 = row - col;//正对角线
            int diagonal2 = row + col;//反对角线
            setMymap(rows, row);
            setMymap(columns, col);
            setMymap(diagonals1, diagonal1);
            setMymap(diagonals2, diagonal2);
            lampSet.add(MAX_NUM * row + col);
        }

        int[] res = new int[queryCount];
        int k = 0;

        for (int[] query : queries) {//遍历查询
            int row = query[0];//行
            int col = query[1];//列
            int diagonal1 = row - col;//正对角线
            int diagonal2 = row + col;//反对角线
            if (rows.containsKey(row) || 
            		columns.containsKey(col) || 
            		diagonals1.containsKey(diagonal1)  || 
            		diagonals2.containsKey(diagonal2) ){
                res[k++] = 1;
            }
            else {
				res[k++] = 0;
			}
            // 关掉当前询问位置和周围相邻8个位置的灯
            closeNeighborLamp(row ,col);
        }
        return res;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值