【2022/04/24-第290场单周赛】复盘

总结
这次题目的知识点比较基础。主要时间花费在了第三题,还是要看清楚变量范围条件的提示。
Q1.多个数组求交集
-
题意理解:
输出在每个所给数组中都存在的数,即取交集。 -
初始思路:
莫名其妙搞得很复杂,用两个哈希表来记录当前数组和下一数组存在的数,然后做与运算。浪费了很多时间。
class Solution {
public:
vector<int> intersection(vector<vector<int>>& nums) {
vector<int> h1(1010, 0), h2(1010, 0);
for(int i = 0; i < nums[0].size(); ++i){
h1[nums[0][i]] = 1;
}
for(int i = 1; i < nums.size(); ++i){
for(int j = 0; j < nums[i].size(); ++j){
h2[nums[i][j]] = h1[nums[i][j]];
}
for(int j = 0; j < 1010; ++j){
h1[j] = h2[j];
h2[j] = 0;
}
}
vector<int> ret;
for(int i = 0; i < 1010; ++i){
if(h1[i])
ret.push_back(i);
}
return ret;
}
};
- 改进解法:
用哈希表记录每个数出现次数,出现次数等于数组数量的值就是结果。
class Solution {
public:
vector<int> intersection(vector<vector<int>>& nums) {
vector<int> h(1010,0), ret;
for(auto i : nums) for(auto j : i) ++h[j];
for(int i = 0; i < 1010; ++i) if(h[i] == nums.size()) ret.emplace_back(i);
return ret;
}
};
Q2.统计圆内格点数目
复盘:
-
题意理解:
直角坐标上给出很多圆,返回在圆内的坐标值为整数的点。 -
初始思路:
用一个哈希表记录点,把每个圆内的点加入到哈希表中
class Solution {
public:
double dis(int x1, int y1, int x2, int y2){
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int countLatticePoints(vector<vector<int>>& circles) {
unordered_set<int> st;
for(auto i : circles){
int x1 = i[0], y1 = i[1], r = i[2];
for(int i = x1 - r; i <= x1 + r; ++i){
for(int j = y1 - r; j <= y1 + r; ++j){
if(dis(x1, y1, i, j) <= r) st.insert(i * 1000 + j);
}
}
}
return st.size();
}
};
- 改进解法:
根据数据范围,初始思路枚举每个圆内点重复较多,性能较差。
若是对每个点枚举圆,则有优化空间。
先将去顶可能点坐标上下界,圆按半径从大到小排序,然后对每个可能的点,依次枚举圆。
class Solution {
public:
int countLatticePoints(vector<vector<int>>& circles) {
int ret = 0, minx = INT_MAX, maxx = INT_MIN, miny = INT_MAX, maxy = INT_MIN;
for(auto &c : circles){
minx = min(minx, c[0] - c[2]);
miny = min(miny, c[1] - c[2]);
maxx = max(maxx, c[0] + c[2]);
maxy = max(maxy, c[1] + c[2]);
}
sort(circles.begin(), circles.end(),[] (const vector<int> &a, const vector<int> &b){
return a[2] > b[2];
});
for(int i = minx; i <= maxx; ++i){
for(int j = miny; j <= maxy; ++j){
for(auto &c : circles){
if((i - c[0]) * (i - c[0]) + (j - c[1]) * (j - c[1]) <= c[2] * c[2]){
++ret;
break;
}
}
}
}
return ret;
}
};
Q3.统计包含每个点的矩形数目
-
题意理解:
对于每个点(x,y),确定有多少个给出的原始数对(xi,yi)满足xi>=x && yi>=y。 -
初始思路:
一开始没注意y的取值范围很小,直接暴力超时了。后面根据y轴分组还是做出来了,最后一分钟的提交!
class Solution {
public:
vector<int> countRectangles(vector<vector<int>>& r, vector<vector<int>>& p) {
int rn = r.size(), pn = p.size(), maxy = 0;
vector<int> rh[110], ret(pn, 0);
for(int i = 0; i < rn; ++i){
rh[r[i][1]].push_back(r[i][0]);
maxy = max(maxy, r[i][1]);
}
for(int i = 0; i <= maxy; ++i) sort(rh[i].begin(), rh[i].end());
for(int i = 0; i < pn; ++i){
int x = p[i][0], y = p[i][1];
for(int j = y; j <= maxy; ++j){
if(rh[j].empty()) continue;
if(rh[j][0] >= x){
ret[i] += rh[j].size();
continue;
}
if(rh[j][rh[j].size() - 1] < x) continue;
int l = 0, r = rh[j].size() - 1;
while(l < r){
int mid = (l + r) / 2;
if(rh[j][mid] < x) l = mid + 1;
else r = mid;
}
ret[i] += rh[j].size() - l;
}
}
return ret;
}
};
- 改进思路:
对于分组的遍历也可以二分查找,进一步优化。略了。
Q4.花期内花的数目
-
题意理解:
给出区间(花期),对每个数字(游客到达时间)求出它落在多少个区间内。 -
初始思路
用两个数组记录左边界(开花时间)和右边界(凋谢时间),对这两个数组和游客到达时间排序。
然后用两个指针指示开花时间和凋谢时间,对于每个游客到达时间,完成这一时间前的所有开花凋谢操作,记录花数量。
class Solution {
public:
vector<int> fullBloomFlowers(vector<vector<int>>& f, vector<int>& p) {
int fn = f.size(), pn = p.size();
vector<int> k(fn), g(fn);
vector<int> pp = p;
unordered_map<int, int> mp;
vector<int> ret(pn);
for(int i = 0; i < fn; ++i){
k[i] = f[i][0];
g[i] = f[i][1];
}
sort(k.begin(), k.end());
sort(g.begin(), g.end());
sort(p.begin(), p.end());
int ki = 0, gi = 0, now = 0;
for(int i = 0; i < pn; ++i){
if(mp.find(p[i]) != mp.end()) continue;
while(ki < fn && k[ki] <= p[i]){
++now;
++ki;
}
while(gi < fn && g[gi] < p[i]){
--now;
++gi;
}
mp[p[i]] = now;
}
for(int i = 0; i < pn; ++i) ret[i] = mp[pp[i]];
return ret;
}
};
- 其他思路
对于每个\(person_i\),用先于他的时间\(start\)数减去早于他的时间\(end\)数。
class Solution {
public:
vector<int> fullBloomFlowers(vector<vector<int>> &flowers, vector<int> &persons) {
int n = flowers.size();
vector<int> starts(n), ends(n);
for (int i = 0; i < n; ++i) {
starts[i] = flowers[i][0];
ends[i] = flowers[i][1];
}
sort(starts.begin(), starts.end());
sort(ends.begin(), ends.end());
n = persons.size();
vector<int> ans(n);
for (int i = 0; i < n; ++i)
ans[i] = (upper_bound(starts.begin(), starts.end(), persons[i]) - starts.begin()) -
(lower_bound(ends.begin(), ends.end(), persons[i]) - ends.begin());
return ans;
}
};
浙公网安备 33010602011771号