在一个给定的n个点的平面,找到在某条直线上的最多的点的数量。

【T3】

英文题目:Given n points on a 2D plane, find the maximum number of points
that lie on the same straight line.
中文题目:在一个给定的n个点的平面,找到在某条直线上的最多的点的数量。

大致思路:

给了你一系列点,这会产生很多条直线,如何确定哪些直线上的点的数量听起来就令人头晕,但简化问题后,就看哪些斜率的点数量最多。想了两种办法,一种是利用数据结构哈希表,存每个斜率,以及该斜率的数量点。第二种就不要用数据结构了,暴力求解emmm。

暴力解决

先从简单的暴力求解来解决一下这道题。

  • 首先,将几种特殊简单情况直接判断:容器为空,最大点数maxnum为0;1个点,maxnum为1;2个点,maxnum为2。

  • 接下来,对普遍情况进行处理

    • 我们首先确定思路为
      一个大循环,对所有的点依次遍历进行计算,但是一条直线是由两个点组成的,所以再来一个小循环,对大循环当前的点及其以后的点进行循环,在这个双重循环中会两点确定一条直线,在循环体里计算该直线上的情况。
      (若是小循环也是从头对所有的点进行循环,则会重复计算两遍,可以想一想,1点为大循环时,会计算所有的点和1点组成的直线上的点情况;然后2点为大循环时,则不需要再次计算与1点组成的直线)

      拿到两个点后,在小循环的循环体里计算该直线的情况:

      • 若是两个点x,y相等,则是重复点,用num记录;
      • 若是不相等,则构成一条直线,这个时候再用遍历一遍所有点的方法,寻找和这两个点在同一条直线上的点数,用cnt记录;具体的判断方法则是
        (y1-y2)/(x1-x2)=(y2-y3)/(x2-x3);
        防止分母为零,变形为:x1y2+x2y3+x3y1-x3y2-x2y1-x1y3=0
  • 小循环的最后,比较maxnum与直线上相同斜率点数cnt大小,将大值赋给maxnum;

  • 大循环的最后比较maxnum与num的大小,将大值赋给maxnum。为什么将重复点单独拿出来记录比较?是为了保障当重复点数量多于某条直线上的数量情况发生时,计算结果最大点数应该为重复点的数量。

    最后,返回maxnum值即可。

    • 代码实现思路
class Solution {
public:
    int maxPoints(vector<Point> &points){
        int maxnum=0;  //用来存储点数最多的数量
      
        //根据容器大小进行简单的判断,针对特殊情况给max赋值
        if(points.size()<=0){ 
            maxnum=0;
        }else if(points.size()==1){
            maxnum=1;
        }else if(points.size()==2){
            maxnum=2;
        }else{//普遍情况
            for(int i=0;i<points.size();i++){
                int num=1;  //把i这个点已经算作1
                
                for(int j=i+1;j<points.size();j++){
                    int cnt=0;
                    int  x1=points[i].x,y1=points[i].y;
                    int  x2=points[j].x,y2=points[j].y;
                    
                    if(x1==x2&&y1==y2){ //若是重复点,则直接记录x1这个点的num值多少
                        num++;
                        continue;
                    }else {   //若不是重复点,则x1,x2形成一条直线,则计算所有的点在这条直线上的数量
                            for(int k=0; k<points.size();k++){
                               // int x3=points[k].x,y3=points[k].y;
                                int  x3=points[k].x,y3=points[k].y;
                                if(x1*y2+x2*y3+x3*y1-x3*y2-x2*y1-x1*y3==0){
                                    //说明1、2、3点共线
                                   cnt++;
                                }
                            }
                            maxnum=max(cnt,maxnum);  //更新max
                    }
             }
                 maxnum=max(maxnum,num);
        }
        
    }
        return maxnum;
    }
};

哈希表法稍后进行尝试。
ps:动手实现时wo就hh了。菜鸡深刻体悟到xia图给人间带来的美好:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值