给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
示例 1:
输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
| o
| o
| o
+------------->
0 1 2 3 4
示例2:
输入: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
输出: 4
解释:
^
|
| o
| o o
| o
| o o
+------------------->
0 1 2 3 4 5 6
class Solution {
private:
static bool cmp(vector<int> &pointA, vector<int> &pointB) //比较函数
{
if(pointA.size() != 2 || pointB.size() != 2) return true;
if(pointA[0] != pointB[0])
{
return pointA[0] < pointB[0];
}
else
{
return pointA[1] < pointB[1];
}
}
//判断三个点是否在同一条直线上,使用乘法来判断
bool isLine(vector<int> &pointA, vector<int> &pointB, vector<int> &pointC)
{
if(pointA.size() != 2 || pointB.size() != 2 || pointC.size() != 2) return false;
long temp1 = ((long)pointC[1]-pointB[1]) * ((long)pointC[0]-pointA[0]);
long temp2 = ((long)pointC[1]-pointA[1]) * ((long)pointC[0]-pointB[0]);
return (temp1 == temp2 ? true : false);
}
public:
int maxPoints(vector<vector<int>>& points) {
if(points.size() == 0 || points[0].size() == 0) return 0;
int size = points.size();
if(size < 3) return size;
int maxPointNum = 0, count1 = 1, count2 = 1;
sort(points.begin(), points.end(), cmp); //先排序处理
for(int i = 0; i < size-2; i++)
{
count1 = 1;
while(i < size-3 && points[i][0] == points[i+1][0] && points[i][1] == points[i+1][1]) //剔除重复的点
{
count1++;
i++;
}
for(int j = i+1; j < size-1; j++)
{
count2 = 1;
while(j < size-2 && points[j][0] == points[j+1][0] && points[j][1] == points[j+1][1])
{
count2++;
j++;
}
int tmp = count1 + count2;
for(int k = j+1; k < size; k++)
{
if(isLine(points[i], points[j], points[k]))
{
tmp++;
}
}
maxPointNum = max(maxPointNum, tmp);
}
}
return maxPointNum;
}
};
这道题处理有两个巧妙之处,1、先排序处理,这样方便后续剔除重复的点 2、使用乘法判断三个点是否在同一条直线上;用3个for循环遍历,注意循环结束的条件