{"id":4896,"date":"2019-02-24T10:18:24","date_gmt":"2019-02-24T18:18:24","guid":{"rendered":"https:\/\/zxi.mytechroad.com\/blog\/?p=4896"},"modified":"2019-02-24T10:26:47","modified_gmt":"2019-02-24T18:26:47","slug":"leetcode-1001-grid-illumination","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/hashtable\/leetcode-1001-grid-illumination\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 1001. Grid Illumination"},"content":{"rendered":"\n<p>On a&nbsp;<code>N x N<\/code>&nbsp;grid of cells, each cell&nbsp;<code>(x, y)<\/code>&nbsp;with&nbsp;<code>0 &lt;= x &lt; N<\/code>&nbsp;and&nbsp;<code>0 &lt;= y &lt; N<\/code>&nbsp;has a lamp.<\/p>\n\n\n\n<p>Initially, some number of lamps are on.&nbsp;&nbsp;<code>lamps[i]<\/code>&nbsp;tells us the location of the&nbsp;<code>i<\/code>-th lamp that is on.&nbsp; Each lamp that is on illuminates every square on its x-axis, y-axis, and both diagonals (similar to a Queen in chess).<\/p>\n\n\n\n<p>For the i-th query&nbsp;<code>queries[i] = (x, y)<\/code>, the answer to the query is 1 if the cell (x, y) is illuminated, else 0.<\/p>\n\n\n\n<p>After each query&nbsp;<code>(x, y)<\/code>&nbsp;[in the order given by&nbsp;<code>queries<\/code>], we turn off any&nbsp;lamps that are at cell&nbsp;<code>(x, y)<\/code>&nbsp;or are adjacent 8-directionally (ie., share a corner or edge with cell&nbsp;<code>(x, y)<\/code>.)<\/p>\n\n\n\n<p>Return an array of answers.&nbsp; Each&nbsp;value&nbsp;<code>answer[i]<\/code>&nbsp;should be equal to the answer of the&nbsp;<code>i<\/code>-th query&nbsp;<code>queries[i]<\/code>.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted crayon:false\"><strong>Input: <\/strong>N = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,0]]\n<strong>Output: <\/strong>[1,0]\n<strong>Explanation: <\/strong>\nBefore performing the first query we have both lamps [0,0] and [4,4] on.\nThe 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:\n1 1 1 1 1\n1 1 0 0 1\n1 0 1 0 1\n1 0 0 1 1\n1 1 1 1 1\nThen 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:\n1 0 0 0 1\n0 1 0 0 1\n0 0 1 0 1\n0 0 0 1 1\n1 1 1 1 1\nBefore 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.\n<\/pre>\n\n\n\n<p><strong>Note:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><code>1 &lt;= N &lt;= 10^9<\/code><\/li><li><code>0 &lt;= lamps.length &lt;= 20000<\/code><\/li><li><code>0 &lt;= queries.length &lt;= 20000<\/code><\/li><li><code>lamps[i].length == queries[i].length == 2<\/code><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution: HashTable<\/strong><\/h2>\n\n\n\n<p>use lx, ly, lp, lq to track the # of lamps that covers each row, col, diagonal, antidiagonal<\/p>\n\n\n\n<p>Time complexity: O(|L| + |Q|)<br>Space complexity: O(|L|)<\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua, running time: 460 ms, 82.2 MB\nclass Solution {\npublic:\n  vector<int> gridIllumination(int N, vector<vector<int>>& lamps, vector<vector<int>>& queries) {\n    unordered_set<long> s;\n    unordered_map<int, int> lx, ly, lp, lq;\n    for (const auto& lamp : lamps) {\n      const int x = lamp[0];\n      const int y = lamp[1];\n      s.insert(static_cast<long>(x) << 32 | y);\n      ++lx[x];\n      ++ly[y];\n      ++lp[x + y];\n      ++lq[x - y];\n    }\n    vector<int> ans;\n    for (const auto& query : queries) {\n      const int x = query[0];\n      const int y = query[1];      \n      if (lx.count(x) || ly.count(y) || lp.count(x + y) || lq.count(x - y)) {\n        ans.push_back(1);       \n        for (int tx = x - 1; tx <= x + 1; ++tx)\n          for (int ty = y - 1; ty <= y + 1; ++ty) {\n            if (tx < 0 || tx >= N || ty < 0 || ty >= N) continue;\n            const long key = static_cast<long>(tx) << 32 | ty;\n            if (!s.count(key)) continue;\n            s.erase(key);\n            if (--lx[tx] == 0) lx.erase(tx);\n            if (--ly[ty] == 0) ly.erase(ty);\n            if (--lp[tx + ty] == 0) lp.erase(tx + ty);\n            if (--lq[tx - ty] == 0) lq.erase(tx - ty);\n          }\n      } else {\n        ans.push_back(0);\n      }\n    }\n    return ans;\n  }\n};\n<\/pre>\n\n<\/div><h2 class=\"tabtitle\">C++ v2<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua, running time: 444 ms, 82.2 MB\nclass Solution {\npublic:\n  vector<int> gridIllumination(int N, vector<vector<int>>& lamps, vector<vector<int>>& queries) {\n    unordered_set<long> s;\n    unordered_map<int, int> lx, ly, lp, lq;\n    for (const auto& lamp : lamps) {\n      const int x = lamp[0];\n      const int y = lamp[1];\n      s.insert(static_cast<long>(x) << 32 | y);\n      ++lx[x];\n      ++ly[y];\n      ++lp[x + y];\n      ++lq[x - y];\n    }\n    vector<int> ans;\n    auto dec = [](unordered_map<int, int>& m, int key) {\n      auto it = m.find(key);\n      if (it->second == 1)\n        m.erase(it);\n      else\n        --it->second;\n    };\n    for (const auto& query : queries) {\n      const int x = query[0];\n      const int y = query[1];      \n      if (lx.count(x) || ly.count(y) || lp.count(x + y) || lq.count(x - y)) {\n        ans.push_back(1);       \n        for (int tx = x - 1; tx <= x + 1; ++tx)\n          for (int ty = y - 1; ty <= y + 1; ++ty) {\n            if (tx < 0 || tx >= N || ty < 0 || ty >= N) continue;\n            const long key = static_cast<long>(tx) << 32 | ty;\n            auto it = s.find(key);\n            if (it == s.end()) continue;\n            s.erase(it);\n            dec(lx, tx);\n            dec(ly, ty);\n            dec(lp, tx + ty);\n            dec(lq, tx - ty);            \n          }\n      } else {\n        ans.push_back(0);\n      }\n    }\n    return ans;\n  }\n};\n<\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>On a&nbsp;N x N&nbsp;grid of cells, each cell&nbsp;(x, y)&nbsp;with&nbsp;0 &lt;= x &lt; N&nbsp;and&nbsp;0 &lt;= y &lt; N&nbsp;has a lamp. Initially, some number of lamps are&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[70],"tags":[7,217,82,468],"class_list":["post-4896","post","type-post","status-publish","format-standard","hentry","category-hashtable","tag-board","tag-hard","tag-hashtable","tag-nqueen","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/4896","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/comments?post=4896"}],"version-history":[{"count":4,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/4896\/revisions"}],"predecessor-version":[{"id":4900,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/4896\/revisions\/4900"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=4896"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=4896"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=4896"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}