【LeetCode练习】[困难]1001. 网格照明
1001. 网格照明
题目来源
算法思想:二维数组,回溯
题目:
照明覆盖情况分析:
- columns 行列长度范围: 0 到 n - 1
- diagonals1 正对角线范围 i - j : - ( n - 1 ) 到 n-1,
- diagonals2 反对角线范围 i + j : 0 到 2 * ( n - 1 ),
- 利用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;
}
}