示例图
给定二维平面上的 N 点作为一对 (x, y) 坐标,我们需要找到位于同一条线上的最大点数。
例子:
输入:points[] = {-1, 1}, {0, 0}, {1, 1},
{2, 2}, {3, 3}, {3, 4}
输出:4
那么位于同一条线上的点的最大数量为 4,这些点分别是 {0, 0}, {1, 1}, {2, 2}, {3, 3}
我们可以通过以下方法解决上述问题 - 对于每个点 p,计算其与其他点的斜率,并使用地图记录有多少个点具有相同的斜率,通过这种方式我们可以找出有多少个点与 p 在同一条线上。对于每个点继续执行相同的操作并更新迄今为止找到的最大点数。
实施过程中需要注意以下几点:
1、如果两个点是 (x1, y1) 和 (x2, y2),则它们的斜率将是 (y2 – y1) / (x2 – x1),这可能是一个双精度值,并且可能导致精度问题。为了消除精度问题,我们将斜率视为对 ((y2 – y1), (x2 – x1)) 而不是比率,并在插入到映射之前通过它们的 gcd 减少对。在下面的代码点中,垂直或重复的点被单独处理。
2、如果我们使用c++ 中的 unordered_map或Java 中的 HashMap来存储斜率对,则解决方案的总时间复杂度将为 O(n^2),空间复杂度将为 O(n)。
示例代码:
/* C# program to find maximum number of point
which lie on same line */
using System;
using System.Collections.Generic;
class GFG {
static int gcd(int p, int q)
{
if (q == 0) {
return p;
}
int r = p % q;
return gcd(q, r);
}
static int N = 6;
// method to find maximum collinear point
static int maxPointOnSameLine(int[, ] points)
{
if (N < 2)
return N;
int maxPoint = 0;
int curMax, overlapPoints, verticalPoints;
Dictionary<string, int> slopeMap
= new Dictionary<string, int>();
// looping for each point
for (int i = 0; i < N; i++) {
curMax = overlapPoints = verticalPoints = 0;
// looping from i + 1 to ignore same pair again
for (int j = i + 1; j < N; j++) {
// If both point are equal then just
// increase overlapPoint count
if (points[i, 0] == points[j, 0]
&& points[i, 1] == points[j, 1])
overlapPoints++;
// If x co-ordinate is same, then both
// point are vertical to each other
else if (points[i, 0] == points[j, 0])
verticalPoints++;
else {
int yDif = points[j, 1] - points[i, 1];
int xDif = points[j, 0] - points[i, 0];
int g = gcd(xDif, yDif);
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
// Convert the pair into a string to use
// as dictionary key
string pair = Convert.ToString(yDif)
+ " "
+ Convert.ToString(xDif);
if (!slopeMap.ContainsKey(pair))
slopeMap[pair] = 0;
// increasing the frequency of current
// slope in map
slopeMap[pair]++;
curMax
= Math.Max(curMax, slopeMap[pair]);
}
curMax = Math.Max(curMax, verticalPoints);
}
// updating global maximum by current point's
// maximum
maxPoint = Math.Max(maxPoint,
curMax + overlapPoints + 1);
slopeMap.Clear();
}
return maxPoint;
}
// Driver code
public static void Main(string[] args)
{
int[, ] points = { { -1, 1 }, { 0, 0 }, { 1, 1 },
{ 2, 2 }, { 3, 3 }, { 3, 4 } };
Console.WriteLine(maxPointOnSameLine(points));
}
}
// This code is contributed by phasing17
输出:
4
时间复杂度: O(n 2 logn),其中 n 表示字符串长度。
辅助空间:O(n)。