1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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时,计算他们的距离,并记录进哈希表中,代码表述如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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代码开头
1 | for ( int i = 0 ; i < points.length ; i ++ ) |
为什么这样就可以取到每个枢纽点i,这样取到的不是应该是二维数组中的每一行嘛?
另外我也不理解最后的求距离的公式
1 2 3 4 | 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老师了!