示例图
给定二维平面上的 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)。
示例代码:
/* Java program to find maximum number of point
which lie on same line */
import java.util.*;
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;
HashMap<String, Integer> slopeMap = new HashMap<>();
// 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 = (yDif) + " " + (xDif);
if (!slopeMap.containsKey(pair))
slopeMap.put(pair, 0);
// increasing the frequency of current
// slope in map
slopeMap.put(pair,
slopeMap.get(pair) + 1);
curMax = Math.max(curMax,
slopeMap.get(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;
}
public static void main(String[] args)
{
int points[][] = { { -1, 1 }, { 0, 0 }, { 1, 1 },
{ 2, 2 }, { 3, 3 }, { 3, 4 } };
System.out.println(maxPointOnSameLine(points));
}
}
输出:
4
时间复杂度: O(n 2 logn),其中 n 表示字符串长度。
辅助空间:O(n)。