- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~
- 本人Gitee账号:路由器,欢迎关注获取博客内容源码。
文章目录- 一、多个数组求交集
- 二、统计圆内格点数目
- 三、统计包含每个点的矩形数目
- 四、花期内花的数目
- 五、扯淡
6041. 多个数组求交集
因为数组中所有元素互不相同,所以我们可以把每个元素出现的次数统计到一个哈希表中,然后出现次数为n(n是二维数组nums
的一位数组个数),因为答案要求升序排列返回,所以我们可以用map
来替代哈希表。
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的,但是第三题比赛的时候没调出来。。。哎。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)