回旋镖的数量
- 题目
- 函数原型
- 边界判断
- 算法设计:查找表
题目
给定平面上 对不同的点,“回旋镖” 是由点表示的元组
,其中
和
之间的距离和
和
找到所有回旋镖的数量。你可以假设 最大为
,所有点的坐标在闭区间
示例:
输入:
[[0,0],[1,0],[2,0]]
输出:
2
解释:
两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
函数原型
C
的函数原型:
int numberOfBoomerangs(int** points, int pointsSize, int* pointsColSize){}
边界判断
int numberOfBoomerangs(int** points, int pointsSize, int* pointsColSize){}
算法设计:查找表
思路:题目说,使得
i、j
俩点的距离等于i、k
俩点的距离。那i
就是一个枢纽,查找距离i
,有相同距离的点。
算法步骤:
- 定一个点
i
,求所有点到i
的距离的平方的出现次数 - 对于点
i
,扫描一遍,其他的点到点i
的距离(下图的第一列)
P.S. 距离计算公式:
- 用一个哈希表来存出现次数,在查找表中 [
],对应的键存储的是距离(第一列),对应的值存储的是多少个距离
i
相同的点(第二列)
第三列,是可能性。如果有
个距离
i
相同的点,就有 - 求完距离后,再求由多少种可能回旋镖,即固定点
i
,j
和k
的可能性有多少种
根据排列组合公式,如果有个点的相对距离相等,就有
- 遍历下一个点,直到结束
#define MAX_N 500
int cmp(const void* a, const void* b)
{
return *(int*)a > *(int*)b;
}
int numberOfBoomerangs(int** points, int pointsSize, int* pointsColSize)
{
if (points == NULL || pointsSize < 3 || pointsSize > 500) {
return 0;
}
int distance[MAX_N] = {0}; // 距离数组
int sum = 0;
int i; // 指针,选择锚点
int j; // 指针,计算距离
for (i = 0; i < pointsSize; i++) {
// 计算每一点到点 i 的距离
for (j = 0; j < pointsSize; j++) {
distance[j] = (points[i][0] - points[j][0]) * (points[i][0] - points[j][0]) +
(points[i][1] - points[j][1]) * (points[i][1] - points[j][1]);
}
// 对距离按升序排序
qsort(distance, pointsSize, sizeof(int), cmp);
int currCount = 1; // 当前计数
// 遍历排序后的距离,统计个数
for (j = 1; j < pointsSize; j++) {
if (distance[j] != distance[j - 1]) {
sum += currCount * (currCount - 1);
currCount = 1;
} else {
currCount++;
}
}
// 记得统计最后一个单词
sum += currCount * (currCount - 1);
}
return sum;
}
- 时间复杂度:
- 空间复杂度: