给定二维平面上的 N 个点作为 (x, y) 坐标对,我们需要找到位于同一条线上的最大点数。
例子:
Input : points[] = {-1, 1}, {0, 0}, {1, 1},
{2, 2}, {3, 3}, {3, 4}
Output : 4
Then maximum number of point which lie on same
line are 4, those point are {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)
C++
/* C/C++ program to find maximum number of point
which lie on same line */
#include
#include
using namespace std;
// method to find maximum colinear point
int maxPointOnSameLine(vector< pair > points)
{
int N = points.size();
if (N < 2)
return N;
int maxPoint = 0;
int curMax, overlapPoints, verticalPoints;
// here since we are using unordered_map
// which is based on hash function
//But by default we don't have hash function for pairs
//so we'll use hash function defined in Boost library
unordered_map, int,boost::
hash > > slopeMap;
// 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] == points[j])
overlapPoints++;
// If x co-ordinate is same, then both
// point are vertical to each other
else if (points[i].first == points[j].first)
verticalPoints++;
else
{
int yDif = points[j].second - points[i].second;
int xDif = points[j].first - points[i].first;
int g = __gcd(xDif, yDif);
// reducing the difference by their gcd
yDif /= g;
xDif /= g;
// increasing the frequency of current slope
// in map
slopeMap[make_pair(yDif, xDif)]++;
curMax = max(curMax, slopeMap[make_pair(yDif, xDif)]);
}
curMax = max(curMax, verticalPoints);
}
// updating global maximum by current point's maximum
maxPoint = max(maxPoint, curMax + overlapPoints + 1);
// printf("maximum colinear point
// which contains current point
// are : %d\n", curMax + overlapPoints + 1);
slopeMap.clear();
}
return maxPoint;
}
// Driver code
int main()
{
const int N = 6;
int arr[N][2] = {{-1, 1}, {0, 0}, {1, 1}, {2, 2},
{3, 3}, {3, 4}};
vector< pair > points;
for (int i = 0; i < N; i++)
points.push_back(make_pair(arr[i][0], arr[i][1]));
cout << maxPointOnSameLine(points) << endl;
return 0;
}
Python3
def maxPoints(points):
n=len(points)
# upto two points all points will be part of the line
if n<3:
return n
max_val=0
# looping for each point
for i in points:
# Creating a dictionary for every new
# point to save memory
d = {}
dups = 0
cur_max = 0
# pairing with all other points
for j in points:
if i!=j:
if j[0]==i[0]: #vertical line
slope='inf'
else:
slope=float(j[1]-i[1])/float(j[0]-i[0])
# Increasing the frequency of slope and
# updating cur_max for current point(i)
d[slope] = d.get(slope,0)+1
cur_max=max(cur_max, d[slope])
# if both points are equal same increase
# duplicates count.
# Please note that this will also increment
# when we map it with itself.
# we still do it because we will not have to
# add the extra one at the end.
else:
dups+=1
max_val=max(max_val, cur_max+dups)
return max_val
# Driver code
points = [(-1, 1), (0, 0), (1, 1), (2, 2), (3, 3), (3, 4)]
print(maxPoints(points))
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。