leetcode-1001:网格照明(自定义哈希集合)

简介: leetcode-1001:网格照明(自定义哈希集合)

题目

题目链接

在大小为 n x n 的网格 grid 上,每个单元格都有一盏灯,最初灯都处于 关闭 状态。

给你一个由灯的位置组成的二维数组 lamps ,其中 lamps[i] = [rowi, coli] 表示 打开 位于 grid[rowi][coli] 的灯。即便同一盏灯可能在 lamps 中多次列出,不会影响这盏灯处于 打开 状态。

当一盏灯处于打开状态,它将会照亮 自身所在单元格 以及同一 行 、同一 列 和两条 对角线 上的 所有其他单元格 。

另给你一个二维数组 queries ,其中 queries[j] = [rowj, colj] 。对于第 j 个查询,如果单元格 [rowj, colj] 是被照亮的,则查询结果为 1 ,否则为 0 。在第 j 次查询之后 [按照查询的顺序] ,关闭 位于单元格 grid[rowj][colj] 上及相邻 8 个方向上(与单元格 grid[rowi][coli] 共享角或边)的任何灯。

返回一个整数数组 ans 作为答案, ans[j] 应等于第 j 次查询 queries[j] 的结果,1 表示照亮,0 表示未照亮。

示例 1:

输入:n = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,0]]
输出:[1,0]
解释:最初所有灯都是关闭的。在执行查询之前,打开位于 [0, 0] 和 [4, 4] 的灯。第 0 次查询检查 grid[1][1] 是否被照亮(蓝色方框)。该单元格被照亮,所以 ans[0] = 1 。然后,关闭红色方框中的所有灯。

第 1 次查询检查 grid[1][0] 是否被照亮(蓝色方框)。该单元格没有被照亮,所以 ans[1] = 0 。然后,关闭红色矩形中的所有灯。
• 1

示例 2:

输入:n = 5, lamps = [[0,0],[4,4]], queries = [[1,1],[1,1]]
输出:[1,1]

示例 3:

输入:n = 5, lamps = [[0,0],[0,4]], queries = [[0,4],[0,1],[1,4]]
输出:[1,1,0]

解题

方法一:哈希

理论参考链接

代码参考链接

我们可以设计四个记录器(4个哈希map)。之所以设计记录器是因为,每点亮一个灯,就必然会点亮“一行”,“一列”,“一个正对角线”,“一个反对角线”。我们不再需要去记录每一个格子的“光源亮度”(会超时)。

如果两盏同一行的灯,所处的行的计数就会变成2。这意味着,只有当两盏灯同时熄灭,才能让这一行的计数变成0(也就是变黑)。

查询的时候,只要行、列、正对角、反对角任何一个有光源,必定导致该格子是亮的。然后删除8邻域(或当前)内的灯就行了。

struct hash_fn{
    size_t operator()(const pair<int,int>&p)const{
        static hash<long long> hash_ll;
        return hash_ll(p.first+(static_cast<long long>(p.second)<<32));
    }
};
class Solution {
public:
    unordered_map<int,int> rows;//行哈希
    unordered_map<int,int> cols;//列哈希
    unordered_map<int,int> postive;//正对角线哈希
    unordered_map<int,int> negative;//副对角线哈希
    unordered_set<pair<int,int>,hash_fn> lampSet;//集合(记录灯的位置)
    vector<int> gridIllumination(int n, vector<vector<int>>& lamps, vector<vector<int>>& queries) {
        // auto hash_fn=[](const pair<int,int>&p)->size_t{
        //     static hash<long long> hash_ll;
        //     return hash_ll(p.first+(static_cast<long long>(p.second)<<32));
        // };
        // unordered_set<pair<int,int>,decltype(hash_fn)> lampSet(0,hash_fn);
        for(vector<int>& lamp:lamps){
            int row=lamp[0];
            int col=lamp[1];
            if(lampSet.count(pair<int,int>(row,col))) continue;//可能有重复的灯(测试样例比较恶心)
            rows[row]++;
            cols[col]++;
            postive[row-col]++;
            negative[col+row]++;
            lampSet.insert({row,col});
        }
        vector<int> res;
        for(vector<int>& query:queries){
            res.push_back(state(query[0],query[1]));//查询
            turnOff(query[0],query[1],n);//关灯 
        }
        return res;
    }
    //获取当前状态(是否照明)
    bool state(int row,int col){
        return bool(rows[row]+cols[col]+postive[row-col]+negative[col+row]);
    }
    //关灯(当前和八邻域)
    void turnOff(int row,int col,int n){
        for(int i:{-1,0,1}){
            if(row+i>=0&&row+i<n){
                for(int j:{-1,0,1}){
                    if(col+j>=0&&col+j<n){
                        if(lampSet.count(pair<int,int>(row+i,col+j))){
                            lampSet.erase(pair<int,int>(row+i,col+j));
                            rows[row+i]--;
                            cols[col+j]--;
                            postive[row+i-col-j]--;
                            negative[col+j+row+i]--;
                        }
                    }
                }
            }
        }
    }
};


相关文章
|
2月前
《LeetCode》—— 哈希
《LeetCode》—— 哈希
|
4月前
leetcode-1044:最长重复子串(滚动哈希)
leetcode-1044:最长重复子串(滚动哈希)
28 0
|
5月前
|
算法 测试技术 C++
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
|
6天前
[leetcode] 705. 设计哈希集合
[leetcode] 705. 设计哈希集合
|
4月前
|
算法 测试技术 C#
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
【动态规划】【广度优先搜索】LeetCode:2617 网格图中最少访问的格子数
|
4月前
leetcode-6110:网格图中递增路径的数目
leetcode-6110:网格图中递增路径的数目
22 1
|
4月前
|
Go
golang力扣leetcode 1001.网格照明
golang力扣leetcode 1001.网格照明
15 0
|
9月前
|
存储 机器学习/深度学习
LeetCode-1001 网格照明
LeetCode-1001 网格照明
|
2月前
|
机器学习/深度学习 算法
力扣刷题日常(一)
力扣刷题日常(一)
20 2
|
2月前
|
存储 索引
《LeetCode》—— LeetCode刷题日记
《LeetCode》—— LeetCode刷题日记

热门文章

最新文章