牛客网LeetCode算法题详解:max-points-on-a-line

该博客详细介绍了LeetCode题目‘max-points-on-a-line’的解题思路,从二维平面上的点出发,讨论如何通过斜率判断多个点是否共线。博主提出初始思路,包括考虑斜率为0的特殊情况,以及如何优化判断过程,避免分母为0的问题。最后给出了算法的逻辑,并解释了当点的数量小于3时的特殊情况。
摘要由CSDN通过智能技术生成

欢迎访问我的个人博客(点击进入)

max-points-on-a-line

1.题干:

对于给定的n个位于同一二维平面上的点,求最多能有多少个点位于同一直线上
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
给出的数据结构:

/**
 * Definition for a point.
 * class Point {
 *     int x;
 *     int y;
 *     Point() { x = 0; y = 0; }
 *     Point(int a, int b) { x = a; y = b; }
 * }
 */
public class Solution {
    public int maxPoints(Point[] points) {
       
    }
}

2.思路分析

最初的分析思路如下:

  1. 首先根据题干,可以提取出这几个关键字:二维平面,最多,同一直线
  2. 再观察给出的数据结构,包含两个变量x,y
  3. 由二维平面和数据结构中的变量可以抽象成一个坐标轴,x为横坐标,y为纵坐标
  4. 再根据同一直线和坐标轴可以联想到,确定两点在一条直线的方式为斜率k,只要斜率k相等两点便在一条直线上

思路中存在的问题:

  1. 在坐标轴中,垂直于x轴的线是没有斜率的(x/y)y为0,所以需要考虑到这一点
  2. 如果两个点重合,也需要考虑为共线

思路中可以继续改进的点:

  1. 判断分母为0,过于繁琐,我们应该想一个办法解决这个问题,让判断的等式变为一个乘法
    进行简单的推导,过程如下:

通过这个推导,我们可以就可以忽略分母为0带来的影响了

最后的思路整理:

  1. 当传入数组长度小于3时,直接返回数组长度即可(两点一线,一个点,没有点)
  2. 这个算法考虑穷举法,首先在循环外部保存一个变量res,用于保存找到的结果,并且在每一轮循环中,与之比较
  3. 开始循环,由于上图中的推导过程涉及三个点,所以需要在最外层循环获得两个点,points[i]和points[i - 1],定义一个count保存当前可以共线的点数,通过这两个点计算出dx,dy,再保存一个点的x,y值,方便后面使用
  4. 首先判断,dx,dy是否全部都是0,如果全部都是0,则进行循环,判断points中的每个点是否与x,y相减都为0,若相等count++
  5. 否则,循环每个点,判断条件为(代入公式):(point.x - x) * dy = (point.y - y) * dx,若相等count++
  6. 最后在判断count和res的大小关系

3.代码实现

public int maxPoints(Point[] points) {
        if (points.length < 3) {
            return points.length;
        }
        int res = 0;
        for (int i = 1; i < points.length; i++) {
            int count = 0;
            int x = points[i].x;
            int y = points[i].y;
            int dx = x - points[i - 1].x;
            int dy = y - points[i - 1].y;
            if (dx == 0 && dy == 0) {
                for (int j = 0; j < points.length; j++) {
                    if (points[j].x == x && points[j].y == y) {
                        count++;
                    }
                }
            } else {
                for (int j = 0; j < points.length; j++) {
                    if ((points[j].x - x)*dy == (points[j].y - y)*dx) {
                        count++;
                    }
                }
            }
            res = Math.max(res, count);
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值