LeetCode 1001. 网格照明题解

1001. 网格照明题解

题目来源:1001. 网格照明

2022.02.08 每日一题

今年的第一道困难,可以采用哈希表来进行求解

根据题意,需要统计行、列、主对角线、副对角线四个方向的亮着的灯

由于行是 (0,a)、列是 (b,0)都可以通过变成一维的坐标,因此我们也可以将两个对角线转换成为一维的数组

在坐标系中,y 可以由 x 表示 $ y = kx +b $

本题中,只有主副两条对角线,因此 k 的值只有 ±1 两个值,因此我们可以通过一些简单的运算来将对角线转为一维变量

主对角线:$ x + y = x + (-x) + b_i=b_i $

副对角线:$ x - y = x - (x + b_j)=-b_j $

由此就将二维转变成为了一维的变量

具体思路:

建立四个哈希表统计各个方位点亮的灯,以及一个集合统计亮着的灯,如果点亮则在四个哈希表中添加对应的值,如果熄灭,则减去对应的值

具体代码以及注释如下

C++代码

class Solution {
public:
    vector<int> gridIllumination(int n, vector<vector<int>> &lamps, vector<vector<int>> &queries) {
        // 定义一个 dir 数组,记录周围九个方向的格子
        vector<vector<int>> dir = {{-1, -1},
                                   {-1, 0},
                                   {-1, 1},
                                   {0,  1},
                                   {0,  0},
                                   {0,  -1},
                                   {1,  -1},
                                   {1,  0},
                                   {1,  1}};
        // 定义四个哈希表,分别代表行、列、正对角线、反对角线,用来存储亮着的房间
        unordered_map<int, int> Row, List, diagonal, antiDiagonal;
        // 建立一个集合统计是亮的灯泡
        set<pair<int, int>> O;
        // 定义一个函数,令四个哈希表中的值加一
        auto change = [&](int &x, int &y, int o) {
            Row[x] += o, List[y] += o, diagonal[x - y] += o, antiDiagonal[x + y] += o;
        };
        // 遍历循环 lamps 数组统计点亮的灯
        for (vector<int> &lamp: lamps) {
            int x = lamp[0], y = lamp[1];
            // 如果这个灯从未被点亮则在点亮灯的合集之中加入这盏灯
            if (O.count(make_pair(x, y)) == 0) {
                // 将未在集合中的灯加入到集合之中
                O.insert(make_pair(x, y));
                // 集合所在灯的四个哈希表之中都加一
                change(x, y, 1);
            }
        }
        // 定义一个结果数组
        vector<int> res;
        // 遍历 queries 数组,进行查询
        for (vector<int> q: queries) {
            // 将判断的结果放入 res 数组之中
            res.push_back(Row[q[0]] || List[q[1]] || diagonal[q[0] - q[1]] || antiDiagonal[q[0] + q[1]]);
            // 查找九个方位
            for (vector<int> d: dir) {
                int x = q[0] + d[0], y = q[1] + d[1];
                // 如果存在亮着的灯就关闭,并且将对应亮的灯泡减一
                if (O.count(make_pair(x, y))) {
                    O.erase(make_pair(x, y));
                    change(x, y, -1);
                }
            }
        }
        // 返回结果
        return res;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值