[447].迴旋鏢的數量

 


題目

給定平面上 nn 對不同的點,“迴旋鏢” 是由點表示的元組 (i,j,k)(i, j, k) ,其中 iijj 之間的距離和 iikk 之間的距離相等(需要考慮元組的順序)。

找到所有迴旋鏢的數量。你可以假設 nn 最大爲 500500,所有點的座標在閉區間 [10000,10000][-10000, 10000] 中。

示例:

輸入:
[[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相同的點(第二列)

    第三列,n(n1)n*(n-1) 是可能性。如果有 nn 個距離i相同的點,就有 n(n1)n*(n-1) 排列方案。

  • 求完距離後,再求由多少種可能迴旋鏢,即固定點ijk的可能性有多少種

    根據排列組合公式,如果有 nn 個點的相對距離相等,就有 n(n1)n*(n-1) 序列對。

  • 遍歷下一個點,直到結束

#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;
}
  • 時間複雜度:Θ(n2)\Theta(n^{2})
  • 空間複雜度:Θ(n)\Theta(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章