leetcode 149. 直线上最多的点数

给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。

 

示例 1:


输入:points = [[1,1],[2,2],[3,3]]
输出:3
示例 2:


输入:points = [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出:4
 

提示:

1 <= points.length <= 300
points[i].length == 2
-104 <= xi, yi <= 104
points 中的所有点 互不相同

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-points-on-a-line
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1:每两个点之间求出斜率和相位,用一个长度为4的数组arr来记录。

(1)因为斜率有可能是分数,所以采用arr的前两位来记录此斜率:arr[0] 分母, arr[1]分子,所以需要先求出分母和分子的最大公约数来约分(采用辗转相除法)。

(2)数组的3, 4 位来记录这个这两个点和 X 轴相交的时候的坐标点,原理同上。

2:把这个数组转换为String,当作map的key,map的value 表示相同点的出现的次数。

3:因为每个点都有重复计算,并且计算的值是 1 + 2 + ... + n = value,为了求n,对value 乘以2 开方 +1。

4:当直线与X周平行的时候,需要单独判断,记录与Y周的交点作为key即可。
思路比较简单,就是实现比较耗时。。。

    public int maxPoints(int[][] points) {
        int length = points.length;
        if (length < 3) {
            return length;
        }
        Map<String, Integer> map = new HashMap<>(length * length);

        int max = 1;
        String key;
        for (int i = 0; i < length - 1; i++) {
            for (int j = i + 1; j < length; j++) {
                int[] a = points[i];
                int[] b = points[j];
                int x = a[0] - b[0];
                int y = a[1] - b[1];

                if (y== 0) {
                    key = String.valueOf(a[1]);
                } else {
                    int min = min(x, y);
                    x /= min;
                    y /= min;
                    int x1 = a[0] * y - a[1] * x;
                    int y1 = y;
                    min = min(x1, y1);
                    x1 /= min;
                    y1 /= min;
                    int[] arr = new int[]{x, y, x1, y1};
                    key = Arrays.toString(arr);
                }
                Integer value = map.get(key);
                if (value == null) {
                    map.put(key, 1);
                } else {
                    map.put(key, value + 1);
                    max = Math.max(value + 1, max);
                }

            }
        }
        return (int) Math.pow(max << 1, 0.5) + 1;
    }
    
    public static int min(int x, int y) {
        if (x == 0) {
            return y;
        }
        int a = x < 0 ? ~x + 1 : x;
        int b = y < 0 ? ~y + 1 : y;
        if (a < b) {
            int t = a;
            a = b;
            b = t;
        }
        while (b != 0) {
            if (a == b) {
                break;
            } else {
                int k = a % b;
                a = b;
                b = k;
            }
        }
        return x < 0 ? ~a + 1 : a;
    }

 

posted @ 2021-06-24 10:54  旺仔古李  阅读(135)  评论(0编辑  收藏  举报