149. Max Points on a Line

149. Max Points on a Line

对于含有一系列坐标点的向量,求此平面上某直线最多的点的数目。

由平面几何知识:一个初始点+方向可以确定一条直线,故分两重循环:

第一重是初始点a

   第二重是剩余的某点b,由b:

      b与a重合,则a所在的所有的直线上的点都加1

      b不与a重合,则构成一个方向,方向由斜率表示(对于垂直方向斜率无穷故单独考虑)且该方向上点数目加1。

原始代码:

/**
 * Definition for a point.
 * struct Point {
 *     int x;
 *     int y;
 *     Point() : x(0), y(0) {}
 *     Point(int a, int b) : x(a), y(b) {}
 * };
 */
class Solution {
public:
int maxPoints(vector<Point>& points){
if(points.empty())return 0;
if(points.size()==1)return 1;
int res=0;
for(int i=0;i<points.size();i++){ 
    int curmax=1;
    map<double,int>k_cnt;//斜率-直线上的点数目
    int again=0;
    int vnum=0;//考虑斜率便不能垂直,故单独计数
    for(int j=0;j<points.size();j++)
    {
	if(j!=i){
	    int dx=points[i].x-points[j].x;
	    int dy=points[i].y-points[j].y;
	    if(dx==0&&dy==0)again++;//重合
	    else if(dx==0){if(vnum==0)vnum=2;else vnum++;curmax=max(curmax,vnum);}//垂直
	    else{
                double k=(double)dy/(double)dx;
		if(k_cnt[k]==0)k_cnt[k]=2;
		else k_cnt[k]++;
		curmax=max(curmax,k_cnt[k]);
	        }//存在斜率时候
	         } 
    }

    res=max(res,curmax+again);
                                 }
return res;
                                      }
};
AC不了:

由于k的斜率是浮点数,存在存储精度问题,当k很大时趋于相同故这里选择存在dy/dx的最简分数形式,这样可以精确表示效率:

改进代码:

int gcd(int x,int y){
int z=y;
while(y!=0){
    z=y;
    y=x%y;
    x=z;
              }
return x;
                   }//两个数最大公约数
int maxPoints(vector<Point>& points){
if(points.empty())return 0;
if(points.size()==1)return 1;
int res=0;
for(int i=0;i<points.size();i++){ 
    int curmax=1;
    //map<double,int>k_cnt;//斜率-直线上的点数目
    map<pair<int,int>,int>k_cnt;
    int again=0;
    int vnum=0;//考虑斜率便不能垂直,故单独计数
    for(int j=0;j<points.size();j++)
    {
	if(j!=i){
	    int dx=points[i].x-points[j].x;
	    int dy=points[i].y-points[j].y;
	    if(dx==0&&dy==0)again++;//重合
	    else if(dx==0){if(vnum==0)vnum=2;else vnum++;curmax=max(curmax,vnum);}//垂直
	    else{
                /*double k=(double)dy/(double)dx;
		if(k_cnt[k]==0)k_cnt[k]=2;
		else k_cnt[k]++;
		curmax=max(curmax,k_cnt[k]);*/
		int g=gcd(dx,dy);
		dx/=g;dy/=g;
		if(k_cnt[make_pair(dx,dy)]==0)k_cnt[make_pair(dx,dy)]=2;
		else k_cnt[make_pair(dx,dy)]++;
		curmax=max(curmax,k_cnt[make_pair(dx,dy)]);
	        }//存在斜率时候
	         } 
    }

    res=max(res,curmax+again);
                                 }
return res;
                                      }




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值