【程序员面试金典】面试题 16.14. 最佳直线

【程序员面试金典】面试题 16.14. 最佳直线

题目描述

描述:给定一个二维平面及平面上的 N 个点列表Points,其中第i个点的坐标为Points[i]=[Xi,Yi]。请找出一条直线,其通过的点的数目最多。

设穿过最多点的直线所穿过的全部点编号从小到大排序的列表为S,你仅需返回[S[0],S[1]]作为答案,若有多条直线穿过了相同数量的点,则选择S[0]值较小的直线返回,S[0]相同则选择S[1]值较小的直线返回。

示例:

输入: [[0,0],[1,1],[1,0],[2,0]]
输出: [0,2]
解释: 所求直线穿过的3个点的编号为[0,2,3]

提示:

2 <= len(Points) <= 300
len(Points[i]) = 2

解题思路

思路1:最直观的想法是,按照编号顺序,先固定两个点i和j,两个点肯定可以确定一条直线,即初始cnt等于2,然后再遍历后面的点k,判断k是否在i和j所构成的直线上,如果在则将cnt加一,遍历完k后,再判断cnt是否大于maxCnt,如果是则更新maxCnt,并将两个点编号更新为i和j。

vector<int> bestLine(vector<vector<int>>& points) 
{
   int maxCnt=0;
   vector<int> res(2);
   for(int i=0;i<points.size();i++)
   {
      for(int j=i+1;j<points.size();j++)
      {
          //先固定两个点
          int cnt=2;
          long x1=points[i][0]-points[j][0];
          long y1=points[i][1]-points[j][1];
          for(int k=j+1;k<points.size();k++)
          {
             long x2=points[i][0]-points[k][0];
             long y2=points[i][1]-points[k][1];
             //如果斜率相等则表示在同一条直线上
             if(x1*y2==x2*y1)
                cnt++;
          }
          if(cnt>maxCnt)
          {
             maxCnt=cnt;
             res[0]=i;
             res[1]=j;
          }
        }
    }
    return res;
}

总结:注意,判断i、j、k三点是否在同一直线上,可以判断(xi-xj)/(yi-yj)是否与(xi-xk)/(yi-yk)相等,又由于可能存在xi=xj或者xi=xk的情况,即直线为垂直线,故将除法转换为乘法,即判断(xi-xj)*(yi-yk)与(xi-xk)*(yi-yj)是否想等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值