持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
题目描述
给你一个在 X-Y 平面上的点构成的数据流。设计一个满足下述要求的算法:
添加 一个在数据流中的新点到某个数据结构中。可以添加 重复 的点,并会视作不同的点进行处理。
给你一个查询点,请你从数据结构中选出三个点,使这三个点和查询点一同构成一个 面积为正 的 轴对齐正方形 ,统计 满足该要求的方案数目。
轴对齐正方形 是一个正方形,除四条边长度相同外,还满足每条边都与 x-轴 或 y-轴 平行或垂直。
实现 DetectSquares 类:
- DetectSquares() 使用空数据结构初始化对象
- void add(int[] point) 向数据结构添加一个新的点 point = [x, y]
- int count(int[] point) 统计按上述方式与点 point = [x, y] 共同构造 轴对齐正方形 的方案数。
示例 1:
输入: ["DetectSquares", "add", "add", "add", "count", "count", "add", "count"] [[], [[3, 10]], [[11, 2]], [[3, 2]], [[11, 10]], [[14, 8]], [[11, 2]], [[11, 10]]] 输出: [null, null, null, null, 1, 0, null, 2]
哈希表法
初步的思路分析:我是想着先把同一列的上点找出来,然后可以根据边长把剩下两个点找出来即可,接下来就是数据结构的选择,因为是根据横纵两条射线来查找,所以两个哈希表就行,分别按照x、y坐标来存储,value没必要存列表,直接存一个Counter,后面拿出来直接加。具体的实现思路如下:
数据结构用哈希表来存储位置和每个位置上点的个数
计算正方形时,先找和输入点point[x,y]横坐标x相同的点集合xSet,然后对于同一个横坐标下,每一个不同的纵坐标y1计算正方形的边长length,这样我们就固定下一条平行于y轴的线
接着判断哈希表中,是否存在横坐标为x - length或x + length的点,对找到横坐标的哈希集合,判断其中是否同时存在y和y1,是则计算正方形的个数
class DetectSquares {
Map<Integer, Map<Integer, Integer>> xPointsCount; // x -> {y1:count, y2:count}
public DetectSquares() {
xPointsCount = new HashMap<>();
}
public void add(int[] point) {
if (!xPointsCount.containsKey(point[0])) xPointsCount.put(point[0], new HashMap<>());
xPointsCount.get(point[0]).put(point[1], xPointsCount.get(point[0]).getOrDefault(point[1], 0) + 1);
}
public int count(int[] point) {
int x12 = point[0], y14 = point[1], res = 0;
for (int y23 : xPointsCount.getOrDefault(x12, new HashMap<>()).keySet()) {
if (y23 == y14) continue;
int count2 = xPointsCount.get(x12).get(y23);
int edge = Math.abs(y23 - y14);
res += count2 * xPointsCount.getOrDefault(x12 + edge, new HashMap<>()).getOrDefault(y23, 0) *
xPointsCount.getOrDefault(x12 + edge, new HashMap<>()).getOrDefault(y14, 0) +
count2 * xPointsCount.getOrDefault(x12 - edge, new HashMap<>()).getOrDefault(y23, 0) *
xPointsCount.getOrDefault(x12 - edge, new HashMap<>()).getOrDefault(y14, 0);
}
return res;
}
}
最后
温馨提示:看不懂题目就画个图吧,一图解千惑啊,其实这个题目和我大学时参加的省赛中的某一题有些相似,那个稍微简单一些,是给你四个点坐标,判断围绕起来是否是矩形。本题在难搞题目的基础上,加上计数的方式。