原题链接:. - 力扣(LeetCode)
翻译成人话:points数组中选择3个点组成一组(i, j ,k),如果其中i到j的距离和i到k的距离相等,就可以构成一个回旋镖,求一共有几组这样的三元组(j,k可互换)。
这是一道hash模拟题,思路如下:
1.第一层循环依次遍历每一个点i
2.第二层循环遍历其他点,hash表记录i与其他点的距离
3.该点形成的回旋镖个数:如果hash[key]>2 则sum+=hash[key]*(hash[key]-1)
4.遍历完所有点即可
并不算难,用c++或者java的hash库很容易,但是C语言难就难在需要自己创建一个hash结构体完成hash查询,如果直接以数组存储所有可能距离遍历查找肯定超时。
笔者不太熟练C的hash建立,这里引用作者StevenG
代码:
typedef struct {
int dis; //平方和
int cnt; //相同平方和的计数值
UT_hash_handle hh;
}HashTable;
void push(HashTable** ht, int dis){
HashTable* tmp;
HASH_FIND_INT(*ht, &dis, tmp);
if(tmp == NULL){
tmp = malloc(sizeof(HashTable));
tmp->dis = dis;
tmp->cnt = 1;
HASH_ADD_INT(*ht, dis, tmp);
}else{
tmp->cnt++;
}
}
int numberOfBoomerangs(int** points, int pointsSize, int* pointsColSize){
int ans = 0, dis;
HashTable* tmp, * s, * cachedDis;
for(int i = 0; i < pointsSize; i++){
cachedDis = NULL;
for(int j = 0; j < pointsSize; j++){
if(i == j){
continue;
}
dis = (points[j][0] - points[i][0]) * (points[j][0] - points[i][0]) + (points[j][1] - points[i][1]) * (points[j][1] - points[i][1]);
push(&cachedDis, dis);
}
HASH_ITER(hh, cachedDis, s, tmp){
ans += s->cnt * (s->cnt - 1);
HASH_DEL(cachedDis, s);
free(s);
}
}
return ans;
}
总结:机试C语言大概率不会考要自己创建hash类的hash问题,而且如果不提供ut_hash函式库就更难了