447. Number of Boomerangs
You are given n points in the plane that are all distinct, where p o i n t s [ i ] = [ x i , y i ] points[i] = [x_i, y_i] points[i]=[xi,yi]. A boomerang is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters).
Return the number of boomerangs.
Example 1:
Input: points = [[0,0],[1,0],[2,0]]
Output: 2
Explanation: The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]].
Example 2:
Input: points = [[1,1],[2,2],[3,3]]
Output: 2
Example 3:
Input: points = [[1,1]]
Output: 0
Constraints:
- n == points.length
- 1 <= n <= 500
- points[i].length == 2
- − 1 0 4 < = x i , y i < = 1 0 4 -10^4 <= x_i, y_i <= 10^4 −104<=xi,yi<=104
- All the points are unique.
From: LeetCode
Link: 447. Number of Boomerangs
Solution:
Ideas:
1. HashMap Structure:
- We use a custom HashMap struct with a simple hash function and linked list chaining for collision resolution. Each point uses a hash map to store distances to other points.
2. Calculate Squared Distances:
- For each pair of points (i, j), calculate distSquared = (x[i] - x[j])^2 + (y[i] - y[j])^2. This avoids floating-point inaccuracies and is sufficient for comparing distances.
3. Counting Boomerangs:
- For each distance count count found in the hash map, the number of boomerangs is 2 * count, because any pair of points j, k that are equidistant from i can form two distinct boomerangs (i, j, k) and (i, k, j).
4. Freeing Memory:
- After processing each point, free the memory used by its hash map to avoid memory leaks.
Code:
typedef struct HashNode {
int key;
int value;
struct HashNode *next;
} HashNode;
typedef struct {
HashNode *buckets[500];
} HashMap;
// Hash function
int hash(int key) {
return abs(key) % 500;
}
// Create a new hashmap
HashMap* createHashMap() {
HashMap* map = (HashMap*)malloc(sizeof(HashMap));
for (int i = 0; i < 500; i++) {
map->buckets[i] = NULL;
}
return map;
}
// Insert or update key-value in hashmap
void put(HashMap* map, int key, int value) {
int index = hash(key);
HashNode *node = map->buckets[index];
while (node) {
if (node->key == key) {
node->value += value;
return;
}
node = node->next;
}
HashNode *newNode = (HashNode*)malloc(sizeof(HashNode));
newNode->key = key;
newNode->value = value;
newNode->next = map->buckets[index];
map->buckets[index] = newNode;
}
// Get value from hashmap
int get(HashMap* map, int key) {
int index = hash(key);
HashNode *node = map->buckets[index];
while (node) {
if (node->key == key) {
return node->value;
}
node = node->next;
}
return 0;
}
// Free hashmap
void freeHashMap(HashMap* map) {
for (int i = 0; i < 500; i++) {
HashNode *node = map->buckets[i];
while (node) {
HashNode *temp = node;
node = node->next;
free(temp);
}
}
free(map);
}
int numberOfBoomerangs(int** points, int pointsSize, int* pointsColSize) {
int result = 0;
for (int i = 0; i < pointsSize; i++) {
HashMap* map = createHashMap();
for (int j = 0; j < pointsSize; j++) {
if (i == j) continue;
int dx = points[i][0] - points[j][0];
int dy = points[i][1] - points[j][1];
int distSquared = dx * dx + dy * dy;
int count = get(map, distSquared);
result += 2 * count; // count * (count - 1) becomes 2 * count for each point
put(map, distSquared, 1);
}
freeHashMap(map);
}
return result;
}