直线上最多的点数问题

这篇博客讨论了如何解决LeetCode上的一个算法问题——找出直线上最多有多少个共线点。文章详细介绍了三种可能的共线情况:水平线、垂直线和斜线,并提供了使用HashMap存储斜率及其对应点数的解决方案。代码中包含对斜率的计算和化简,以及如何更新最大点数的方法。
摘要由CSDN通过智能技术生成

直线上最多的点数问题

作者:Grey

原文地址:

博客园:直线上最多的点数问题

CSDN:直线上最多的点数问题

题目描述

LeetCode 149. Max Points on a Line

思路

共线的点,有如下可能

第一种可能:点在同一条水平线上,即纵坐标的一样。

第二种可能:点在同一个竖直线上,即横坐标一样。

第三种可能:点连成的线共斜率,即斜率一致。

三种可能分别如下图

image

image

image

共水平线,共竖线的值单独统计,针对共斜率的线,我们设计如下结构来存

Map<Integer,Map<Integer,Integer>> map = new HashMap<>();

map通过如下方式来存斜率,例如:

Map<Integer,Integer> m = new HashMap<>();
m.put(3,30);
map.put(4,m);

表示:斜率为3/4的点有30个。

再如:

Map<Integer,Integer> m = new HashMap<>();
m.put(7,10);
map.put(5,m);

表示:斜率为7/5的点有10个。

假设两个点的坐标为(x1,y1)(x2,y2),那么斜率tan = (y1-y2)/(x1-x2),由于要用分数来表示,所以要化简,即先求x2-x1y2-y1的最大公约数(辗转相除法)。

    private static int gcd(int m, int n) {
        return n == 0 ? m : gcd(n, m % n);
    }

完整代码如下:

    public static int maxPoints(int[][] points) {
        if (points == null || points.length == 0) {
            return 0;
        }
        if (points.length == 1) {
            return 1;
        }
        int max = 1;
        // map形如(3,(4,10)) 表示:斜率为3/4的点有10个
        Map<Integer, Map<Integer, Integer>> map = new HashMap<>();
        for (int i = 0; i < points.length; i++) {
            map.clear();
            int sameY = 1;
            int sameX = 1;
            int sameSlope = 1;
            int x1 = points[i][0];
            int y1 = points[i][1];
            for (int j = i + 1; j < points.length; j++) {
                int x2 = points[j][0];
                int y2 = points[j][1];
                if (x2 == x1) {
                    sameX++;
                } else if (y2 == y1) {
                    sameY++;
                } else {
                    int rangeY = y2 - y1;
                    int rangeX = x2 - x1;
                    int z = gcd(rangeX, rangeY);
                    rangeY = rangeY / z;
                    rangeX = rangeX / z;
                    if (map.containsKey(rangeY)) {
                        Map<Integer, Integer> m = map.get(rangeY);
                        if (m.containsKey(rangeX)) {
                            m.put(rangeX, m.get(rangeX) + 1);
                            map.put(rangeY, m);
                        } else {
                            m.put(rangeX, 2);
                            map.put(rangeY, m);
                        }
                    } else {
                        Map<Integer, Integer> m = new HashMap<>();
                        m.put(rangeX, 2);
                        map.put(rangeY, m);
                    }
                    sameSlope = Math.max(map.get(rangeY).get(rangeX), sameSlope);
                }
                max = Math.max(max, Math.max(Math.max(sameX, sameY), sameSlope));
            }
        }
        return max;
    }

    private static int gcd(int m, int n) {
        return n == 0 ? m : gcd(n, m % n);
    }

更多

算法和数据结构笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreyZeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值