public class Solution { public int numberOfBoomerangs(int[][] points) { int res = 0; for( int i = 0 ; i < points.length ; i ++ ){ // record中存储 点i 到所有其他点的距离出现的频次 HashMap<Integer, Integer> record = new HashMap<Integer, Integer>(); for(int j = 0 ; j < points.length ; j ++) if(j != i){ // 计算距离时不进行开根运算, 以保证精度 int dis = dis(points[i], points[j]); if(record.containsKey(dis)) record.put(dis, record.get(dis) + 1); else record.put(dis, 1); } for(Integer dis: record.keySet()) res += record.get(dis) * (record.get(dis) - 1); } return res; } private int dis(int[] pa, int pb[]){ return (pa[0] - pb[0]) * (pa[0] - pb[0]) + (pa[1] - pb[1]) * (pa[1] - pb[1]); } public static void main(String[] args) { int[][] points = {{0, 0}, {1, 0}, {2, 0}}; System.out.println((new Solution()).numberOfBoomerangs(points)); } }
bobo老师,看了这节课还有您的java解法,我仍然没有理解这道题,麻烦bobo老师可以点拨一下~
首先我对于题目解法的理解:遍历二维数组中的每一点,作为枢纽点i,同时在对每一个枢纽点遍历时,创建哈希表,再对二维数组每一个点j进行一次遍历,当i 不等于j时,计算他们的距离,并记录进哈希表中,代码表述如下:
public int numberOfBoomerangs(int[][] points) { //遍历二维数组的枢纽点i for(int i = 0; i < points.length; i++){ for(int j = 0; j < points[i].length; j++){ Map<Integer, Integer> freq = new HashMap<>(); //遍历二维数组的每个与枢纽点i进行比较的点j for(int k = 0 ; k < points.length; k++){ for(int l = 0; l < points.length; l++){ if(points[i][j] != points[k][l]){ //计算两点之间距离 } } } } } }
但是这样的话,每次遍历一次二维数组寻找枢纽点i,都要O(n^2)的时间复杂度,如果此时再遍历一次二维数组,寻找每个和枢纽点i比较的点j,时间复杂度就应该来到了O(n^4),所以我也不理解您java代码开头
for( int i = 0 ; i < points.length ; i ++ )
为什么这样就可以取到每个枢纽点i,这样取到的不是应该是二维数组中的每一行嘛?
另外我也不理解最后的求距离的公式
private int dis(int[] pa, int pb[]){ return (pa[0] - pb[0]) * (pa[0] - pb[0]) + (pa[1] - pb[1]) * (pa[1] - pb[1]); }
为什么(pa[0],pa[1]),(pb[0],pb[1])可以表示两个点?这个函数传入的pa,pb应该是二维数组中的两个行啊?就像下面这样:
思考很久还是想不通,写了很多读起来很麻烦,辛苦bobo老师了!