zoukankan      html  css  js  c++  java
  • [leetcode] Number of Boomerangs

    Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between iand j equals the distance between i and k (the order of the tuple matters).

    Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).

    Example:

    Input:
    [[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]]

     分析:题目意思理解起来并不是很难,二维数组的每一行代表平面上的一个点,任意一个点到其他两个点距离相同时,视为一个解。这里要注意的是其他两个点也是分先后顺序的,也就是可以看成是一个排列问题。有了这个作为基础,首先想到的就是计算所有点之间的距离,并且用一个二维矩阵保存下来。然后去遍历这个二维矩阵的每一行,假设一行有m个相同距离为1的点,那么就是A(m,2)。
            有了上面的分析,首先想到找排列公式,在网上找了一个递归版本的求排列和组合的代码,用java描述如下:
     1     /**
     2      * 计算阶乘数,即n! = n * (n-1) * ... * 2 * 1 
     3      * @param n
     4      * @return
     5      */
     6     private static long factorial(int n) {
     7         long sum = 1;
     8         while( n > 0 ) {
     9             sum = sum * n--;
    10         }
    11         return sum;
    12     }
    13     /**
    14      * 排列计算公式A<sup>m</sup><sub>n</sub> = n!/(n - m)!
    15      * @param m
    16      * @param n
    17      * @return
    18      */
    19     public static long arrangement(int m, int n) {
    20         return m <= n ? factorial(n) / factorial(n - m) : 0;
    21     }
    22     /**
    23      * 组合计算公式C<sup>m</sup><sub>n</sub> = n! / (m! * (n - m)!)
    24      * @param m
    25      * @param n
    26      * @return
    27      */
    28     public static long combination(int m, int n) {
    29         return m <= n ? factorial(n) / (factorial(m) * factorial((n - m))) : 0;
    30     }

          那么本题的代码如下:

     1     int res = 0;
     2     public int numberOfBoomerangs(int[][] points) {
     3         int n = points.length;
     4         double[][] distance = new double[n][n];
     5         for ( int i = 0 ; i < n ; i ++ ){
     6             for ( int j = 0 ; j < n ; j ++ ){
     7                 distance[i][j] = Math.sqrt((points[j][0]-points[i][0])*(points[j][0]-points[i][0])+(points[j][1]-points[i][1])*(points[j][1]-points[i][1]));
     8             }
     9         }
    10         Map<Double,Integer> map = new HashMap<>();
    11         for ( int i = 0 ; i < n ; i ++ ){
    12             map.clear();
    13             for ( int j = 0 ; j < n ; j ++ ){
    14                 map.put(distance[i][j],map.getOrDefault(distance[i][j],0)+1);
    15             }
    16             for ( int value : map.values() ){
    17                 if ( value >= 2 ) calcnum(value);
    18             }
    19         }
    20         return res;
    21     }
    22     private void calcnum(int value) {
    23         res += factorial(value) / factorial(value-2);
    24     }
    25     private static long factorial(int n) {
    26         long sum = 1;
    27         while( n > 0 ) {
    28             sum = sum * n--;
    29         }
    30         return sum;
    31     }

          最后运行时间117ms,超过94.7%的人。


          但是,还是有很大的优化空间,首先在计算距离矩阵的时候,没必要先全部保存下来然后再遍历,可以一边计算,一边用Map记录;而且对于A(m,2),计算下来的结果就是m*(m-1),所以也没必要再用递归来做了;因为只要找距离相同的点的个数,也不需用求根号了;这样优化下来,第二版代码如下:

     1 class Solution {
     2     public int numberOfBoomerangs(int[][] points) {
     3         int res = 0;
     4         Map<Double,Integer> map = new HashMap<>();
     5         int n = points.length;
     6         for ( int i = 0 ; i < n ; i ++ ){
     7             for ( int j = 0 ; j < n ; j ++ ){
     8                 double d = (points[j][0]-points[i][0])*(points[j][0]-points[i][0])+(points[j][1]-points[i][1])*(points[j][1]-points[i][1]);
     9                 map.put(d,map.getOrDefault(d,0)+1);
    10             }
    11             for ( int value : map.values() ){
    12                 if ( value >= 2 ) res += value*(value-1);
    13             }
    14             map.clear();
    15         }
    16         return res;
    17     }
    18 }

          运行时间97ms,超过99%的人。

  • 相关阅读:
    Codeforces Beta Round #92 (Div. 2 Only) B. Permutations 模拟
    POJ 3281 Dining 最大流 Dinic算法
    POJ 2441 Arrange the BUlls 状压DP
    URAL 1152 Faise Mirrors 状压DP 简单题
    URAL 1039 Anniversary Party 树形DP 水题
    URAL 1018 Binary Apple Tree 树形DP 好题 经典
    pytorch中的forward前向传播机制
    .data()与.detach()的区别
    Argparse模块
    pytorch代码调试工具
  • 原文地址:https://www.cnblogs.com/boris1221/p/9289642.html
Copyright © 2011-2022 走看看