LeetCode第290场周赛前四题题解

- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~

一、多个数组求交集

6041. 多个数组求交集

  因为数组中所有元素互不相同,所以我们可以把每个元素出现的次数统计到一个哈希表中,然后出现次数为n(n是二维数组nums的一位数组个数),因为答案要求升序排列返回,所以我们可以用map<int, int>来替代哈希表。

class Solution {
public:
    vector<int> intersection(vector<vector<int>>& nums) 
    {
        map<int, int> cnt;
        for (auto& p : nums)    
        {
            for (auto num : p)
            {
                ++cnt[num];
            }
        }
        int n = nums.size();
        vector<int> ans;
        for (auto& p : cnt)
        {
            if (p.second == n) ans.push_back(p.first);
        }
        return ans;
    }
};

二、统计圆内格点数目

6042. 统计圆内格点数目

  本题的思路是枚举。首先遍历圆得到所有点区域的左下边界、右下边界、左上边界、右上边界,然后枚举这其中的所有点,看看其是否在某个圆中即可,判断是否在某个圆中可以直接利用点到圆心的距离是否小于等于半径来判断。

class Solution {
public:
    int countLatticePoints(vector<vector<int>>& circles) 
    {
        int ans = 0;
        int xmin = 0x3f3f3f3f;
        int xmax = 0;
        int ymin = 0x3f3f3f3f;
        int ymax = 0;
        for (auto& p : circles)
        {
            xmax = max(xmax, p[0] + p[2]);
            xmin = min(xmin, p[0] - p[2]);
            ymax = max(ymax, p[1] + p[2]);
            ymin = min(ymin, p[1] - p[2]);
        }
        for (int i = xmin; i <= xmax; ++i)
        {
            for (int j = ymin; j <= ymax; ++j)
            {
                bool flag = false;
                for (auto& p : circles)
                {
                    int dist = (i - p[0]) * (i - p[0]) + (j - p[1]) * (j - p[1]);
                    if (dist <= p[2] * p[2])
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag) ++ans;
            }
        }
        return ans;
    }
};

三、统计包含每个点的矩形数目

6043. 统计包含每个点的矩形数目

  关于离散化和差分的知识,可以参考我这篇博客:常见基础算法,进行了解。

  本题的直接思路是二维差分。每个矩形我们认为是给区域(0, 0)->(xi, yi)增加了1,最后对差分数组求二维前缀和,然后对每个点看一看它的值为多少即它处于多少个矩形内。

  但是x的范围非常大,是1e9,y的范围是100,直接看1e9 * 100的二维数组会爆内存,注意到矩形的个数其实只有5e4,所以本题可以离散化。

  另外由于离散化代码一般是默认矩阵是从(1, 1)开始的,因此染色过程我们认为染的点是(1, 1)->(myhash[xi], yi + 1),其中离散化映射到的范围是2往后。

class Solution {
public:
    // 差分的插入
    // b[x1][y1] += c; b[x1][y2 + 1] -= c; b[x2 + 1][y1] -= c; b[x2 + 1][y2 + 1] += c
    void insert(vector<vector<int>>& b, int x1, int y1, int x2, int y2)
    {
        b[x1][y1] += 1, b[x1][y2 + 1] -= 1, b[x2 + 1][y1] -= 1, b[x2 + 1][y2 + 1] += 1;
    }
    vector<int> countRectangles(vector<vector<int>>& rectangles, vector<vector<int>>& points) 
    {
        // 离散化
        vector<int> alls;
        for (auto& p : rectangles)
        {
            alls.push_back(p[0]);
        }
        for (auto& p : points)
        {
            alls.push_back(p[0]);
        }  
        sort(alls.begin(), alls.end());
        // 去重
        alls.erase(unique(alls.begin(), alls.end()), alls.end());
        unordered_map<int, int> myhash;
        int n = alls.size();
        for (int i = 0; i < n; ++i)
        {
            // 映射到[2, n + 1]
            myhash[alls[i]] = i + 2;
        }
        // 差分数组
        vector<vector<int>> b(n + 10, vector<int>(103));
        for (auto& p : rectangles)
        {
            int x = myhash[p[0]], y = p[1] + 1;
            insert(b, 1, 1, x, y);
        }
        // 获得前缀和
        vector<vector<int>> a(n + 10, vector<int>(103));
        for (int i = 1; i <= n + 1; ++i)
        {
            for (int j = 1; j <= 102; ++j)
            {
                // 二维前缀和
                a[i][j] = b[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
            }
        }
        // 找答案
        vector<int> ans;
        for (auto& p : points)
        {
            int x = myhash[p[0]], y = p[1] + 1;
            ans.push_back(a[x][y]);
        }
        return ans;
    }
};

四、花期内花的数目

6044. 花期内花的数目

  其实这题比上一题还简单,一个花期就认为是这个区间都增加了1,因为我们是把所有的花期都统计了以后再来看人的情况,所以可以使用一个一维差分,因为数据范围是1e9但数据个数是5e4,所以可以使用离散化,然后人到了以后就看看这点的值是多少就行。

class Solution {
public:
    void insert(vector<int>& b, int l, int r)
    {
        b[l] += 1, b[r + 1] -= 1;
    }
    vector<int> fullBloomFlowers(vector<vector<int>>& flowers, vector<int>& persons) 
    {
        // 离散化
        vector<int> alls;
        for (auto& p : flowers)
        {
            alls.push_back(p[0]);
            alls.push_back(p[1]);
        }
        for (auto& p : persons)
        {
            alls.push_back(p);
        }
        sort(alls.begin(), alls.end());
        alls.erase(unique(alls.begin(), alls.end()), alls.end());
        unordered_map<int, int> myhash;
        int n = alls.size();
        // 映射到[1, n]
        for (int i = 0; i < n; ++i) myhash[alls[i]] = i + 1;
        // 差分
        vector<int> b(n + 10);
        for (auto& p : flowers)
        {
            int l = myhash[p[0]], r = myhash[p[1]];
            insert(b, l, r);
        }
        // 获得原数组 原数组是差分数组的前缀和
        vector<int> a(n + 10);
        for (int i = 1; i <= n; ++i) a[i] = a[i - 1] + b[i];
        // 获得答案
        vector<int> ans;
        for (int p : persons)
        {
            p = myhash[p];
            ans.push_back(a[p]);
        }
        return ans;
    }
};

五、扯淡

  其实这次有机会AK的,但是第三题比赛的时候没调出来。。。哎。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值