题目
给你一个在 X-Y 平面上的点构成的数据流。设计一个满足下述要求的算法:
添加 一个在数据流中的新点到某个数据结构中。可以添加 重复 的点,并会视作不同的点进行处理。
给你一个查询点,请你从数据结构中选出三个点,使这三个点和查询点一同构成一个 面积为正 的 轴对齐正方形 ,统计 满足该要求的方案数目。
轴对齐正方形 是一个正方形,除四条边长度相同外,还满足每条边都与 x-轴 或 y-轴 平行或垂直。
实现 DetectSquares 类:
DetectSquares() 使用空数据结构初始化对象
void add(int[] point) 向数据结构添加一个新的点 point = [x, y]
int count(int[] point) 统计按上述方式与点 point = [x, y] 共同构造 轴对齐正方形 的方案数。
解题思路
模拟。对于添加的点用List存储,并构建 flag[MAX_LENGTH][MAX_LENGTH]
用于存储每个点的数量,方便判断正方形,这样只需要找对角的点就可以判断。对于每个查询的点,遍历所有的点,看其是否能跟查询的点构成 正方形
的对角,再判断其他两个点,并进行计数。
代码
class DetectSquares {
private List<int[]> mPoints;
public static final int MAX_LENGTH = 1000 + 50;
private int[][] flag;
public DetectSquares() {
mPoints = new ArrayList<>();
flag = new int[MAX_LENGTH][MAX_LENGTH];
}
public void add(int[] point) {
flag[point[0]][point[1]]++;
mPoints.add(point);
}
public int count(int[] point) {
int ans = 0;
for (int[] mPoint : mPoints) {
if (mPoint[0] == point[0] && mPoint[1] == point[1]) continue;
int[] left, right;
if (point[0] < mPoint[0]) {
left = point;
right = mPoint;
} else {
left = mPoint;
right = point;
}
int sub_x, sub_y;
if (left[1] < right[1]) {
sub_x = right[0] - left[0];
sub_y = right[1] - left[1];
if (sub_x != sub_y) continue;
ans += flag[right[0]][left[1]] * flag[left[0]][right[1]];
} else {
sub_x = right[0] - left[0];
sub_y = left[1] - right[1];
if (sub_x != sub_y) continue;
ans += flag[left[0]][right[1]] * flag[right[0]][left[1]];
}
}
return ans;
}
}