力扣 - 447. 回旋镖的数量
题目
思路1(暴力,不推荐)
- 暴力三层循环,搜索所有的结果
- 超时,不推荐
代码
class Solution {
public int numberOfBoomerangs(int[][] points) {
int res = 0;
for (int i = 0; i < points.length; i++) {
for (int j = 0; j < points.length; j++) {
for (int k = 0; k < points.length; k++) {
if (i != j && i != k && j != k) {
int d1 = dis(points[i], points[j]);
int d2 = dis(points[i], points[k]);
if (d1 == d2) {
res++;
}
}
}
}
}
return res;
}
public int dis(int[] point1, int[] point2) {
// 计算两点的距离
return (int) (Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
}
}
复杂度分析
- 时间复杂度:\(O(N^3)\),暴力3层循环,其中 N 表示数组的长度
- 空间复杂度:\(O(1)\)
思路2(哈希表)
- 外层for遍历一遍数组,计算其他点与它的距离
- 每次计算一个点的其他的与它距离时,使用一个新的哈希表,key存储的是他们未开根号的距离,value是存储出现的次数
- 如果value值是1,代表只出现一次
- 如果value值是2,说明刚刚好有两个相等的点,但是排列的方式有两种,如果值为3,排列的方式有6种。即有
n个相同的点,排列方式有n(n-1)种
代码
class Solution {
public int numberOfBoomerangs(int[][] points) {
int res = 0;
for (int i = 0; i < points.length; i++) {
// 计算每个点时使用一个新的哈希表
Map<Integer, Integer> hashtable = new HashMap<>();
for (int j = 0; j < points.length; j++) {
// i != j,因为计算的是其他的点
if (i != j) {
// 获取未开根号的距离
int d = dis(points[i], points[j]);
hashtable.put(d, hashtable.getOrDefault(d, 0) + 1);
}
}
for (Map.Entry<Integer, Integer> entry : hashtable.entrySet()) {
// 因为只有距离相等才会被记录两次,如果没有和他相等的,只会被记录一次,那么我们就忽略
if (entry.getValue() >= 2) {
res += entry.getValue()*(entry.getValue()-1);
}
}
}
return res;
}
public int dis(int[] point1, int[] point2) {
// 计算两点的距离
return (int) (Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
}
}
复杂度分析
- 时间复杂度:\(O(N^2)\),其中 N 为数组的长度
- 空间复杂度:\(O(N^2)\),其中 N 为哈希表的大小,需要使用
N个哈希表记录N个点到其他N-1的距离出现的次数,最坏情况下每个距离都不一样,那么需要的每个哈希表大小为N-1
我走得很慢,但我从不后退!

浙公网安备 33010602011771号