题目描述
Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
我的想法:
1、算法设计很简单的题目,但是真正用数据结构实现起来却不容易的一道题。
2、刚开始考虑分三类进行解决,一类横坐标相同,一类纵坐标相同的点,一类斜率点
3、考虑不周,点的坐标可正可负,还想着用数组下标保存,有点蠢
4、思路半路夭折,看了别人的思路。
int maxPoints(vector<Point> &points) {
int n = points.size();
if (n == 0) return 0;
int maxNum = INT_MIN;
map<int, vector<Point>> k;
set<int> kindK;
int shu[10005] = {0}; //shu[i]表示纵坐标相同是i的点的个数
int heng[10005] = {0}; //heng[i]表示横坐标相同是i的点的个数
int maxX = INT_MIN, maxY = INT_MIN;
int minX = INT_MAX, minY = INT_MAX;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int ix = points[i].x, iy = points[i].y;
maxX = max(ix, maxX);
minX = min(ix, minX);
maxY = max(maxY, iy);
minY = min(iy,minY);
int jx = points[j].x, jy = points[j].y;
maxX = max(jx, maxX);
minX = min(jx, minX);
maxY = max(maxY, jy);
minY = min(jy,minY);
if (ix == jx) { //在一条竖线上,横坐标相同
heng[ix]++;
} else if (iy == jy) {
shu[iy]++;
} else {
int xie = (jy - iy) / (jx - ix);
kindK.insert(xie);
vector<Point> tmp;
tmp = k[xie];
tmp.push_back(points[i]);
tmp.push_back(points[j]);
k[xie] = tmp;
}
}
}
for(int i = minX; i <= maxX; i++){
if(heng[i] == 0) continue;
else{
maxNum = max(maxNum, heng[i]);
}
}
for(int i = minY; i <= maxY; i++){
if(shu[i] == 0) continue;
else{
maxNum = max(maxNum, shu[i]);
}
}
for(auto x : kindK){
vector<Point> tmp = k[x];
int b[10005] = {0};
int maxB = INT_MIN;
for(int i = 0; i < tmp.size(); i++){
int bb = tmp[i].y - x*tmp[i].x;
b[bb]++;
maxB = max(bb,maxB);
}
for(int i = 0; i <= maxB; i++)
}
}
牛客网友的思路:
1.分两层循环枚举,第一遍遍历起始点a,第二遍遍历剩下的点
2.分两类,垂直和有斜率的,要注意计算垂直点不为0时,不能重复计算
链接:https://www.nowcoder.com/questionTerminal/bfc691e0100441cdb8ec153f32540be2?f=discussion
来源:牛客网
/**
* 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<Point> &points) {
int size = points.size();
if(size == 0)
return 0;
else if(size == 1)
return 1;
int ret = 0;
for(int i = 0;i<size;i++){
int curmax = 1;
map<double,int>mp;
int vcnt = 0; //垂直点
int dup = 0; //重复点
for(int j = 0;j<size;j++){
if(j!=i){
double x1 = points[i].x - points[j].x;
double y1 = points[i].y - points[j].y;
if(x1 == 0 && y1 == 0){ //重复
dup++;
}else if(x1 == 0){ //垂直
if(vcnt == 0)
vcnt = 2;
else
vcnt++;
curmax = max(vcnt,curmax);
}else{
double k = y1/x1; //斜率
if(mp[k] == 0)
mp[k] = 2;
else
mp[k]++;
curmax = max(mp[k],curmax);
}
}
}
ret = max(ret,curmax+dup);
}
return ret;
}
};