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. 1 <= N <= 10^9
  2. 0 <= lamps.length <= 20000
  3. 0 <= queries.length <= 20000
  4. 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;
    } 
}

 

posted @ 2019-03-04 15:46  起点菜鸟  阅读(264)  评论(0编辑  收藏  举报