[LeetCode] 1001. Grid Illumination

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].

 

Example 1:

Input: N = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,0]]
Output: [1,0]
Explanation: 
Before performing the first query we have both lamps [0,0] and [4,4] on.
The grid representing which cells are lit looks like this, where [0,0] is the top left corner, and [4,4] is the bottom right corner:
1 1 1 1 1
1 1 0 0 1
1 0 1 0 1
1 0 0 1 1
1 1 1 1 1
Then the query at [1, 1] returns 1 because the cell is lit.  After this query, the lamp at [0, 0] turns off, and the grid now looks like this:
1 0 0 0 1
0 1 0 0 1
0 0 1 0 1
0 0 0 1 1
1 1 1 1 1
Before performing the second query we have only the lamp [4,4] on.  Now the query at [1,0] returns 0, because the cell is no longer lit.

 

Note:

  1. 1 <= N <= 10^9
  2. 0 <= lamps.length <= 20000
  3. 0 <= queries.length <= 20000
  4. lamps[i].length == queries[i].length == 2

 

This problem is similar with Count Pairs of attacking bishop pairs. We can use the same approach to uniquely represent a line of slope 1 or -1 on the edge grids.  A simpler way to uniquely represent all lines with 1 or -1 slope is as following.

For a give grid (x, y), the unique key for positive 1 slope line is x + y and the unique key for negative 1 slope line is x - y.

class Solution {
    class Point {
        int x, y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
        @Override
        public int hashCode() {
            long code = 31 * x   + 37 * y;
            return (int)(code % Integer.MAX_VALUE);
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            Point p = (Point) obj;
            if (x != p.x || y != p.y) {
                return false;
            }
            return true;
        }
    }

    private Set<Point> lampSet = new HashSet<>();
    private Map<Integer, Integer> horizontal = new HashMap<>();
    private Map<Integer, Integer> vertical = new HashMap<>();
    private Map<Integer, Integer> posMap = new HashMap<>();
    private Map<Integer, Integer> negMap = new HashMap<>();    
    
    public int[] gridIllumination(int N, int[][] lamps, int[][] queries) {
        for(int i = 0; i < lamps.length; i++) {
            lampSet.add(new Point(lamps[i][0], lamps[i][1]));
            horizontal.put(lamps[i][0], horizontal.getOrDefault(lamps[i][0], 0) + 1);
            vertical.put(lamps[i][1], vertical.getOrDefault(lamps[i][1], 0) + 1);
            posMap.put(lamps[i][0] + lamps[i][1], posMap.getOrDefault(lamps[i][0] + lamps[i][1], 0) + 1);
            negMap.put(lamps[i][0] - lamps[i][1], negMap.getOrDefault(lamps[i][0] - lamps[i][1], 0) + 1);
        }       
        int[] results = new int[queries.length];
        for(int i = 0; i < queries.length; i++) {
            if(horizontal.getOrDefault(queries[i][0], 0) > 0 
                || vertical.getOrDefault(queries[i][1], 0) > 0
                || posMap.getOrDefault(queries[i][0] + queries[i][1], 0) > 0 
                || negMap.getOrDefault(queries[i][0] - queries[i][1], 0) > 0) {
                results[i] = 1;
            }
            turnOffLamp(queries[i][0], queries[i][1]);
        }
        return results;
    }
    
    private void turnOffLamp(int x, int y) {
        for(int i = -1; i < 2; i++) {
            for(int j = -1; j < 2; j++) {
                Point p = new Point(x + i, y + j);
                if(lampSet.contains(p)) {
                    horizontal.put(x + i, horizontal.get(x + i) - 1);
                    vertical.put(y + j, vertical.get(y + j) - 1);
                    posMap.put(x + i + y + j, posMap.get(x + i + y + j) - 1);
                    negMap.put(x + i - y - j, negMap.get(x + i - y - j) - 1);
                    lampSet.remove(p);
                }                  
            }
        }      
    }
}

 

posted @ 2019-02-26 12:38  Review->Improve  阅读(594)  评论(0编辑  收藏  举报