LeetCode 第 290 场周赛题解
LeetCode 第 290 场周赛题解
多个数组求交集
题目描述:给你\(n\)个集合,求这\(n\)个集合的交集
思路:根据题意模拟即可,可以使用map
辅助
时间复杂度:\(O(mlogm)\) ,其中\(m = \sum\limits_{i = 1}^{n}nums_i.length\)
参考代码:
class Solution {
public:
vector<int> intersection(vector<vector<int>>& nums) {
map<int , int>mp;
for(auto&&num : nums){
for(auto&& n : num) mp[n]++;
}
int n = nums.size();
vector<int>res;
for(auto&& [val , cnt] : mp) if(cnt == n) res.push_back(val);
return res;
}
};
统计圆内格点数目
题目描述:给你\(n\)个圆,问你有多少个格点在这些圆内。
思路:考虑到圆的坐标范围比较小,所以枚举这个范围内的所有格点,然后去枚举所有圆检验一遍即可。
时间复杂度:\(O(300^2n)\)
参考代码:
class Solution {
public:
int countLatticePoints(vector<vector<int>>& circles) {
int res = 0;
for(int i = -100 ; i <= 200 ; ++i){
for(int j = -100 ; j <= 200 ; ++j){
for(auto&& v : circles){
int x = v[0] , y = v[1] , r = v[2];
int dx = (x - i) * (x - i) + (y - j) * (y - j);
if(dx > r * r) continue;
++res;
break;
}
}
}
return res;
}
};
统计包含每个点的矩形数目
题目描述:有\(m\)个左下角在原点的矩形,然后给你\(n\)个点,求每一个点在多少个矩形上。
思路:设矩形的右上角坐标为\((l , r)\),某个点的坐标为\((x , y)\)。那么题目就是求满足\(x \leq l\)且\(y \leq r\)的矩形数量,考虑到\(l,x\)都比较大,那么我们将其按照从小到大排序,然后倒序枚举,每次将所有横坐标大于等于当前枚举点的矩形的纵坐标加入可重集合,然后再去统计可重集合中数值大于等于\(y\)的值的数量,这个可以用树状数组维护或者用桶记录再暴力统计。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
vector<int> countRectangles(vector<vector<int>>& rectangles, vector<vector<int>>& points) {
sort(rectangles.begin() , rectangles.end());
int n = points.size();
for(int i = 0 ; i < n ; ++i) points[i].push_back(i);
sort(points.begin() , points.end());
vector<int>tr(105 , 0);
auto lowbit = [&](int x){return x & -x;};
auto add = [&](int idx){
while(idx <= 100){
tr[idx] ++;
idx += lowbit(idx);
}
return ;
};
auto getSum = [&](int idx){
int sum = 0;
while(idx){
sum += tr[idx];
idx -= lowbit(idx);
}
return sum;
};
vector<int>res(n);
int m = rectangles.size(), idx = 0;
idx = m - 1;
for(int i = n - 1 ; i >= 0 ; --i){
int x = points[i][0] , y = points[i][1] , id = points[i][2];
while(idx >= 0 && rectangles[idx][0] >= x){
add(rectangles[idx][1]);
--idx;
}
int dx = m - idx - 1;
res[id] = dx - getSum(y - 1);
}
return res;
}
};
花期内花的数目
题目描述:给你\(m\)个时间段,表示一种花开花和凋谢的时间,然后给你\(n\)个询问,每个询问给定一个时间time
表示有一个人在\(time\)时来赏花,求他赏花时有多少朵花正在开放。
思路:老套路题目,将开花置为+1
,将凋谢的时间加一的时间节点置为-1
,然后排序;再将询问排序,每次询问前,将所有时间节点小于等于当前枚举的时间节点的信息都遍历一遍并统计一下即可。
时间复杂度:\(O(nlogn)\)
参考代码:
class Solution {
public:
vector<int> fullBloomFlowers(vector<vector<int>>& flowers, vector<int>& persons) {
using PII = pair<int , int>;
vector<PII>nums;
for(auto&& flower: flowers){
nums.push_back({flower[0] , 1});
nums.push_back({flower[1] + 1 , -1});
}
sort(nums.begin() , nums.end());
int n = persons.size();
vector<vector<int>>p(n);
for(int i = 0 ; i < n ; ++i) p[i].push_back(persons[i]) , p[i].push_back(i);
sort(p.begin() , p.end());
vector<int> res(n , 0);
int sum = 0, m = nums.size() , idx = 0;
for(int i = 0 ; i < n ; ++i){
int tm = p[i][0] , id = p[i][1];
while(idx < m && nums[idx].first <= tm){
sum += nums[idx ++].second;
}
res[id] += sum;
}
return res;
}
};
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。