力扣第290场周赛总结

第一题:多个数组求交集

原题链接

题目:

给你一个二维整数数组 nums ,其中 nums[i] 是由 不同 正整数组成的一个非空数组,按 升序排列 返回一个数组,数组中的每个元素在 nums 所有数组 中都出现过。

示例1:

输入:nums = [[3,1,2,4,5],[1,2,3,4],[3,4,5,6]]
输出:[3,4]
解释:
nums[0] = [3,1,2,4,5],nums[1] = [1,2,3,4],nums[2] = [3,4,5,6],在 nums 中每个数组中都出现的数字是 3 和 4 ,所以返回 [3,4] 。

思路:因为二维整数数组中的每个一维数组都是由不同整数组成的非空数组,直接unordered_map记录出现次数,若出现次数等于二维数组中一维数组的个数,则把该数加入答案。

class Solution {
public:
    vector intersection(vector>& nums) {
        unordered_map mp;
        for(int i=0;i ans;
        for(auto &[u,v]:mp){
            if(v==nums.size()){
                ans.push_back(u);
            }
        }
        sort(ans.begin(),ans.end());
        return ans;
    }
};

 

第二题:统计圆内格点数目

原题链接

题目:

给你一个二维整数数组 circles ,其中 circles[i] = [xi, yi, ri] 表示网格上圆心为 (xi, yi) 且半径为 ri 的第 i 个圆,返回出现在 至少一个 圆内的 格点数目 。

示例1:

输入:circles = [[2,2,1]]
输出:5
解释:
给定的圆如上图所示。
出现在圆内的格点为 (1, 2)、(2, 1)、(2, 2)、(2, 3) 和 (3, 2),在图中用绿色标识。
像 (1, 1) 和 (1, 3) 这样用红色标识的点,并未出现在圆内。
因此,出现在至少一个圆内的格点数目是 5 。

 思路:原本想枚举圆看看每个圆有(2r-1)^2+4个点,然后用哈希去重避免添加重复的点,但好像行不通。后来想想点是有上限的,最多四万个点,直接枚举点,看看这些点是否被圆覆盖就行了。这样做也不会有点被重复计算。

class Solution {
public:
    int countLatticePoints(vector>& circles) {
        int ans=0;
        for(int i=0;i<=200;i++){//枚举可能的所有点看看是否被圆覆盖
            for(int j=0;j<=200;j++){//因为枚举的是每个点 所以相同点不会被多次计入答案
                bool ok=false;
                for(int k=0;k

 

第三题:统计包含每个点的矩形数目

原题链接

题目:

给你一个二维整数数组 rectangles ,其中 rectangles[i] = [li, hi] 表示第 i 个矩形长为 li 高为 hi 。给你一个二维整数数组 points ,其中 points[j] = [xj, yj] 是坐标为 (xj, yj) 的一个点。

示例1:

输入:rectangles = [[1,2],[2,3],[2,5]], points = [[2,1],[1,4]]
输出:[2,1]
解释:
第一个矩形不包含任何点。
第二个矩形只包含一个点 (2, 1) 。
第三个矩形包含点 (2, 1) 和 (1, 4) 。
包含点 (2, 1) 的矩形数目为 2 。
包含点 (1, 4) 的矩形数目为 1 。
所以,我们返回 [2, 1] 。

思路:只要满足points[i]<=rectangles[i]和points[j]<=rectangles[j]即可,先把题目给的两个二维数组按从大到小排序,创建一个idx数组存把points排序后各元素原本的下标,把纵坐标满足条件的矩形都加入到res数组中,从小到大排序在二分查找横坐标也满足条件的矩形的个数,因为points是越来越小的,所以前面能满足条件的矩形对后面一定满足,所以res数组不比清空。

class Solution {
public:
    vector countRectangles(vector>& rectangles, vector>& points) {
        sort(rectangles.begin(),rectangles.end(),[](vector &a,vector &b){
            return a[1]>b[1];
        });
        int n=points.size();
        vector idx(n);
        iota(idx.begin(),idx.end(),0);//对范围内元素赋值 0 1 2 3 4 5......n
        sort(idx.begin(),idx.end(),[&](int i,int j){//存Points按从大到小排序的下标
            return points[i][1]>points[j][1];
        });
        vector ans(n),res;
        int i=0;
        for(int id:idx){
            int start=i;
            while(i=points[id][1]){
                res.push_back(rectangles[i++][0]);//纵坐标符合要求把横坐标放入
            }
            if(start

第四题:花期内花的数目

原题链接

题目:

给你一个下标从 0 开始的二维整数数组 flowers ,其中 flowers[i] = [starti, endi] 表示第 i 朵花的 花期 从 starti 到 endi (都 包含)。同时给你一个下标从 0 开始大小为 n 的整数数组 persons ,persons[i] 是第 i 个人来看花的时间。

请你返回一个大小为 n 的整数数组 answer ,其中 answer[i]是第 i 个人到达时在花期内花的 数目 。

示例1:

输入:flowers = [[1,6],[3,7],[9,12],[4,13]], persons = [2,3,7,11]
输出:[1,2,2,2]
解释:上图展示了每朵花的花期时间,和每个人的到达时间。
对每个人,我们返回他们到达时在花期内花的数目。

 思路:flower[i]区间为花期,所以直接用差分数组把区间内的每个时间点加1,表示在这个时间点能看到的花朵的数量加1,但时间点的上限是10e9,若用数组会TLE,所以选择用map离散化。

class Solution {
public:
    vector fullBloomFlowers(vector>& flowers, vector& persons) {
        map diff;//map离散化加差分
        for(auto &f:flowers){
            ++diff[f[0]];
            --diff[f[1]+1];
        }
        int n=persons.size();
        vector idx(n);//
        iota(idx.begin(),idx.end(),0);
        sort(idx.begin(),idx.end(),[&](int i,int j){
            return persons[i] ans(n);
        auto it=diff.begin();
        int sum=0;
        for(int id:idx){
            while(it!=diff.end()&&it->first<=persons[id]){
                sum+=it++->second;//前面差分 后面累加即可
            }
            ans[id]=sum;//把累加结果存入该下标下
        }
        return ans;
    }
};

你可能感兴趣的:(c++,力扣)