leetcode 1001. Grid Illumination
Problem Descriptino:
On a N x N
grid of cells, each cell (x, y)
with 0 <= x < N
and 0 <= y < N
has a lamp.
Initially, some number of lamps are on. lamps[i]
tells us the location of the i
-th lamp that is on. Each lamp that is on illuminates every square on its x-axis, y-axis, and both diagonals (similar to a Queen in chess).
For the i-th query queries[i] = (x, y)
, the answer to the query is 1 if the cell (x, y) is illuminated, else 0.
After each query (x, y)
[in the order given by queries
], we turn off any lamps that are at cell (x, y)
or are adjacent 8-directionally (ie., share a corner or edge with cell (x, y)
.)
Return an array of answers. Each value answer[i]
should be equal to the answer of the i
-th query queries[i]
.
Note:
1 <= N <= 10^9
0 <= lamps.length <= 20000
0 <= queries.length <= 20000
lamps[i].length == queries[i].length == 2
一个N*N的网格,其中一部分网格通过传入的参数lamps[][]数组来在其中的部分格子中放入灯,每盏灯能照亮其所在的行、列和两条对角线。有一个queries[][]的数组来进行多次查询,查看格子是否被灯点亮。每次query之后,被查询的格子和其周围相邻的8个格子的灯全部熄灭。
解体过程:
看到这个题首先想到的是建立一个网格数组boolean[N][N], 大小为N*N, 在棋盘上初始化点亮的灯true, 在棋盘上进行查询和熄灭。 这种方法空间复杂度为N*N。N最大取10^9。此种做法到只MLE。
然后想到了用一个HashSet集合来存String, 每个坐标=x + "," + y。模拟棋盘的方式来查询,单词查询的时间复杂度为O(4N) = O(N),且查询的时候需要多次建立并抛弃无用的String,导致时间复杂度的常数项也很大,会TLE。
看了一下题目的类型为HashMap,用了一个HashSet来存Long,坐标为x*N +y,另外添加四个HashMap(x_count, y_count, sumxy_count, diffxy_count)来分别存储 在x行,y列,x+y为指定值, x-y为指定值的格子被多少盏灯照亮。
采用此种方式, 放灯时候的时间复杂度为O(1) , 查询的时候的复杂度也为 O(1) 。
代码如下:
class Solution { public int[] gridIllumination(int N, int[][] lamps, int[][] queries) { Map<Integer, Integer> x_count = new HashMap<>(); Map<Integer, Integer> y_count = new HashMap<>(); Map<Integer, Integer> sumxy_count = new HashMap<>(); Map<Integer, Integer> diffxy_count = new HashMap<>(); Set<Long> set = new HashSet<>(); for(int i = 0; i < lamps.length; i++) { x_count.put(lamps[i][0], x_count.getOrDefault(lamps[i][0], 0) + 1); y_count.put(lamps[i][1], y_count.getOrDefault(lamps[i][1], 0) + 1); sumxy_count.put(lamps[i][0] + lamps[i][1], sumxy_count.getOrDefault(lamps[i][0] + lamps[i][1], 0) + 1); diffxy_count.put(lamps[i][0] - lamps[i][1], diffxy_count.getOrDefault(lamps[i][0] - lamps[i][1], 0) + 1); set.add((long)lamps[i][0] * (long)N + lamps[i][1]); } int[] res = new int[queries.length]; for(int i = 0; i < queries.length; i++) { res[i] = query(N, queries[i][0], queries[i][1], x_count, y_count, sumxy_count, diffxy_count, set); } return res; } public int query(int N, int i, int j, Map<Integer, Integer> x_count, Map<Integer, Integer> y_count, Map<Integer, Integer> sumxy_count, Map<Integer, Integer> diffxy_count, Set<Long> set) { //System.out.println(x_count.getOrDefault(i, 0) +", "+ y_count.getOrDefault(j, 0) + ", " + sumxy_count.getOrDefault(i + j, 0) + "," + diffxy_count.getOrDefault(i - j, 0)); int res = 0; if(x_count.getOrDefault(i, 0) > 0 || y_count.getOrDefault(j, 0) > 0 || sumxy_count.getOrDefault(i + j, 0) > 0 || diffxy_count.getOrDefault(i - j, 0) > 0) { res = 1; } for(int s = -1; s < 2; s++) { for(int t = -1; t < 2; t++) { int x = s + i, y = t + j; if(x < 0 || x >= N || y < 0 || y >= N) continue; if(set.contains((long)x * N + y)) { set.remove((long)x * N + y); x_count.put(x, x_count.get(x) - 1); y_count.put(y, y_count.get(y) - 1); sumxy_count.put(x + y, sumxy_count.get(x + y) - 1); diffxy_count.put(x - y, diffxy_count.get(x - y) - 1); //System.out.println("delete " + x + "," + y); } } } return res; } }