回旋镖的数量

  • 题目
  • 函数原型
  • 边界判断
  • 算法设计:查找表



 


题目

给定平面上 [447].回旋镖的数量_元组 对不同的点,“回旋镖” 是由点表示的元组 [447].回旋镖的数量_元组_02 ,其中 [447].回旋镖的数量_算法设计_03[447].回旋镖的数量_点到点_04 之间的距离和 [447].回旋镖的数量_算法设计_03[447].回旋镖的数量_算法设计_06

找到所有回旋镖的数量。你可以假设 [447].回旋镖的数量_元组 最大为 [447].回旋镖的数量_元组_08,所有点的坐标在闭区间 [447].回旋镖的数量_元组_09

示例:

输入:
[[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 的距离(下图的第一列)

[447].回旋镖的数量_算法设计_10

P.S. 距离计算公式:

[447].回旋镖的数量_点到点_11

  • 用一个哈希表来存出现次数,在查找表中 [[447].回旋镖的数量_元组_12],对应的键存储的是距离(第一列),对应的值存储的是多少个距离i相同的点(第二列)
    第三列,[447].回旋镖的数量_算法设计_13 是可能性。如果有 [447].回旋镖的数量_算法设计_14 个距离i相同的点,就有 [447].回旋镖的数量_算法设计_13
  • 求完距离后,再求由多少种可能回旋镖,即固定点ijk的可能性有多少种
    根据排列组合公式,如果有 [447].回旋镖的数量_算法设计_14 个点的相对距离相等,就有 [447].回旋镖的数量_算法设计_13
  • 遍历下一个点,直到结束
#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;
}
  • 时间复杂度:[447].回旋镖的数量_点到点_18
  • 空间复杂度:[447].回旋镖的数量_算法设计_19