Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
题意:找到在同一直线上的点的最大个数。
分析:首先看这个题的暴力方法,两点确定一条直线,所以确定下一条直线后,挨个验证剩下的点是不是也在这条直线上,并记录个数,O(n^3)的时间复杂度就可以解决问题,这个量级的时间复杂度很明显是不符合要求的,如何降低时间复杂度呢?
问题的关键就在于如何描述一条直线,和共线这两个问题,而要解决这两个问题的方法很简单,借助一条初中几何的直线性质即可,那就是过同一个点的斜率相同的直线是同一条直线,所以只要固定一个点X,然后计算剩下的点和X的连线斜率,只要是相同的就是共线的,然后借助哈希表就可以记录下不同斜率的出现次数。
在算法实现的时候,要注意除0异常,两点重合的情况,除0异常很简单,判断两个点的横坐标是否相同,如果相同的话则以最大斜率表示。两点重合的情况要设置一个计数器来记录跟固定点重合的点的次数。
代码实现:
public class Solution
{
public int MaxPoints(Point[] points)
{
if (points.Length <= 2)
return points.Length;
Dictionary<float, int> slopes = new Dictionary<float, int>();
int res = 2;
for (int i = 0; i < points.Length; i++)
{
slopes.Clear();
int duplicate = 1;
for (int j = i+1; j < points.Length; j++)
{
if (points[i].x == points[j].x && points[i].y == points[j].y)
duplicate++;
else
{
float slope = points[i].x==points[j].x? (float)Math.Pow(2,31)-1: (float)(points[i].y - points[j].y) / (float)(points[i].x - points[j].x);
if (slopes.ContainsKey(slope))
slopes[slope]++;
else
slopes.Add(slope, 1);
}
}
res = Math.Max(res,duplicate);
foreach (KeyValuePair<float, int> tmp in slopes)
{
res = res > tmp.Value + duplicate ? res : tmp.Value + duplicate;
}
}
return res;
}
}