转载请注明:http://blog.csdn.net/ict2014/article/details/17400345
原题如下:
题目解析:
最先想到的做法就是每次固定一个点,然后计算它同其他所有点的斜率,并且对出现过的斜率进行累加计数。
做的时候,需要注意几点:
1、直线不存在的时候,也就是斜率不存在
2、有重复的点出现。
算法的时间复杂度为O(n^2).
题目代码:
我们可以看如下Accept的代码:
/**
* Definition for a point.
* struct Point {
* int x;
* int y;
* Point() : x(0), y(0) {}
* Point(int a, int b) : x(a), y(b) {}
* };
*/
#include <algorithm>
int cmp(const Point& a, const Point& b);
class Solution {
public:
int maxPoints(vector<Point> &points) {
//点集合为空
if(points.empty()){
return 0;
}
int points_size = points.size();
//点集合数目小于3个,返回点集合大小
if(points_size <= 2){
return points_size;
}
//保存通过某点的斜率-点数目
map<double,int> lines;
int max_points = 0, total, vertical_num;
double k;
for(int i = 0; i < points_size-1; ++i){
lines.clear();
//total保存等于points[i]点的数目
total = 1;
//斜率不存在时,除了i之外的点数目
vertical_num = 0;
for(int j = i+1; j < points_size; ++j){
//等于points[i]时
if(points[i].x == points[j].x &&
points[i].y == points[j].y){
++total;
continue;
}
//斜率不存在
if(points[i].x == points[j].x){
++vertical_num;
}else{
k = (double)(points[i].y - points[j].y)/(points[i].x - points[j].x);
if(lines.find(k) != lines.end()){
++lines[k];
}else{
lines[k] = 1;
}
}
}
//更新最大值
map<double,int>::iterator iter = lines.begin();
for(;iter != lines.end(); ++iter){
if(iter->second > vertical_num){
vertical_num = iter->second;
}
}
vertical_num += total;
if(vertical_num > max_points){
max_points = vertical_num;
}
}
return max_points;
}
};
31-69行是大循环,每次固定一个点,然后求这个点和其他点组成的直线。
38-43是出现重复点的处理,total保存该点出现的次数。
45-48是处理斜率不存在的情况,保存在vertical_num里面。
注意程序中:total保存直线第一个点的次数,lines以及vertical_num保存直线另外一个点出现的次数
因此才会有第65行,进行累加的操作。