给定2D平面上的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))