Given
n
points on a 2D plane, find the maximum number of points that lie on the same straight line.
以每个点为中心,然后遍历剩余点,找到所有的斜率,如果斜率相同,那么一定共线,每次更新最大点数,最后就是结果。排序O(nlog(n))再乘以n个点,总复杂度O(n2logn)
#include
using namespace std;
#include
#include
#include
#include
// Definition for a point. struct Point { int x; int y; Point() : x(0), y(0) {} Point(int a, int b) : x(a), y(b) {} }; class Solution { static bool PointXCompare(const Point &lhs, const Point &rhs) { return lhs.x < rhs.x; } static bool PointYCompare(const Point &lhs, const Point &rhs) { return lhs.y < rhs.y; } static bool FloatCompare(float a, float b) { const float epsilon = 0.000001; return (a - b) < epsilon && (b - a) > -epsilon; } public: int maxPoints(vector
&points) { // IMPORTANT: Please reset any member data you declared, as // the same Solution instance will be reused for each test case. // bug 1: 没有考虑重复点 if (points.size() <= 2) { return points.size(); } int max_count = 2; const float float_max = 3.402823466e+38F ; // 以每个点作为中心,计算其他值到它的slope,并排序,这样如果一样的斜率存在那么一定共线 for (int i = 0; i < points.size() - 1; i++) { // 优化1 当剩余点小于max_point时,退出 if (points.size() - i < max_count) { break; } // 有重复点。。 int repeat_point = 0; vector
slopes(points.size() - i - 1); //只处理剩余点即可,前面的都已经处理过了 int index = 0; //开始计算斜率并排序 for (int j = i + 1; j < points.size(); j++) { if (points[j].x == points[i].x && points[j].y == points[i].y) { repeat_point++; continue; } if (j != i) { if (points[j].x == points[i].x) { //竖直 slopes[index++] = float_max; } else { slopes[index++] = (float)(points[j].y - points[i].y) / (points[j].x - points[i].x); } } } sort(slopes.begin(), slopes.begin() + index); //找到共线的个数 int cur = 0; float first = slopes[0]; int count = 1; while (++cur < index) { if (FloatCompare(slopes[cur], first)) { count++; } else { count = 1; first = slopes[cur]; } max_count = max(max_count, count + 1 + repeat_point); //数量等于斜率的个数加1个数 } //最后需要更新,因为有一部分点没有考虑 if (index == 0) { max_count = max(max_count, 1 + repeat_point); //没有线段,数量等于自己加上重复点数 } else { max_count = max(max_count, count + 1 + repeat_point); //数量等于斜率的个数加重复点个数 } } return max_count; } }; int main() { Solution so; Point p0(1, 1), p1(2, 1), p2(1, 1), p3(2, 1), p4(3, 3), p5(3, 3); //重点考虑 (0, 0), (1, 0), (0, 0); // (1, 1), (1, 1), (1, 1); vector
points; points.push_back(p0); points.push_back(p1); points.push_back(p2); // points.push_back(p3); // points.push_back(p4); // points.push_back(p5); cout << so.maxPoints(points) << endl; return 0; }
以每个点为中心,遍历其他点,找到所有的斜率,但是这是将斜率放到hash表中,O(n2)的复杂度
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
class Solution {
public:
int maxPoints(vector
&points) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
//O(n2)
if ( points.size() <= 2) {
return points.size();
}
const float float_max = std::numeric_limits
::infinity();
int max_count = 2;
//以每个点为中心,计算其他值到它的slope,然后使用hash计数即可
for ( int i = 0; i < points.size() - 1; i++) {
// 优化1 当剩余点小于max_point时,退出
if ( points.size() - i < max_count) {
break;
}
// 有重复点。。
int repeat_point = 0;
unordered_map
line_nums;
float slope;
for ( int j = i + 1; j < points.size(); j++) {
if ( points[j].x == points[i].x && points[j].y == points[i].y) {
repeat_point++;
continue;
}
if ( points[j].x == points[i].x) { //竖直
slope = float_max;
}
else {
slope = ( float)( points[j].y - points[i].y) / (points[j].x - points [i].x);
}
line_nums[slope]++;
}
int max_slope_num = 0;
for (unordered_map
::iterator iter = line_nums.begin(); iter != line_nums.end(); ++iter) {
max_slope_num = max(max_slope_num, iter->second);
}
max_count = max(max_count, repeat_point + max_slope_num + 1);
}
return max_count;
}
};