題目
Given n points
on a 2D plane, find the maximum number of points that lie on the same straight line.
分析
1、首先的想法是根據兩點確定一條直線,之後判斷第三點是否在直線上,爲三層迭代(循環)。時間複雜度O(n^3)。
2、處理重複的點:先把點映射到map中,保存點出現的次數。之後,創建點和次數的結構體,保存到vector中,使用1求得max。
3、使用map的問題,題目已經定義了struct,並且沒有對運算符<進行重載,因此必須額外定義比較規則。方法見:它。
複雜度
注意
5、點的統計規則:curnum += points[k].value;
輸入
CODE
Code1: 結構體內重載<
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
#include <stdexcept>
using namespace std;
struct Point {
int x;
int y;
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
bool operator < (const Point& pointB) const
{
if (x != pointB.x) {
return x < pointB.x;
} else {
return y < pointB.y;
}
}
};
struct PointValue {
Point point;
int value;
PointValue() : value(0) {}
};
/**
* 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 maxnum = 0;
map<Point, int> imap;
insertToMap(points, imap);
vector<PointValue> newPoints;
clearPoints(newPoints, imap);
maxnum = scanVector(newPoints);
return maxnum;
}
void insertToMap(vector<Point> &points, map<Point, int> &imap) {
for (auto itVar = points.begin(); itVar != points.end(); ++itVar) {
Point pVar = *itVar;
auto it = imap.find(pVar);
if (it != imap.end()) {
// already exist
// int t = it->second;
// it->second = t + 1;
++(it->second);
} else {
// insert to imap
imap.insert( make_pair(pVar, 1) );
}
}
}
void clearPoints(vector<PointValue> &points, map<Point, int> &mymap) {
for (auto it = mymap.begin(); it != mymap.end(); ++it) {
PointValue pv;
pv.point = it->first;
pv.value = it->second;
points.push_back(pv);
}
}
int scanVector(vector<PointValue> &points) {
int maxnum = 0;
if (points.size() == 0) {
return 0;
} else if(points.size() == 1) {
return points[0].value;
} else {
// number of points more than two
int vecSize = points.size();
for (int i = 0; i != vecSize; ++i) {
for(int j = i + 1; j != vecSize; ++j) {
// form a line
int curnum = points[i].value + points[j].value;
if (points[i].point.x == points[j].point.x) {
// vertical
for(int k = j + 1; j != vecSize; ++k) {
if (points[i].point.x == points[k].point.x) {
curnum += points[k].value;
// ++curnum;
}
}
} else {
// a line with slope
double slpoe = (static_cast<double>(points[i].point.y - points[j].point.y)) / (points[i].point.x - points[j].point.x);
for(int k = j + 1; k != vecSize; ++k) {
double slope1 = (static_cast<double>(points[i].point.y - points[k].point.y)) / (points[i].point.x - points[k].point.x);
if (slpoe == slope1) {
curnum += points[k].value;
// ++curnum; //it is not right!!!
}
}
}
if (curnum > maxnum) {
maxnum = curnum;
}
}
}
}
return maxnum;
}
// all kinds of lines
};
int main()
{
vector<Point> t1;
vector<Point> t2(1);
vector<Point> t3(2);
vector<Point> t4(2);
Point t;
t.x = 2; t.y = 1;
t4.push_back(t);
t.x = 4; t.y = 2;
t4.push_back(t);
t.x = 1; t.y = 2;
t4.push_back(t);
Solution so;
cout << so.maxPoints(t1) << endl;
cout << so.maxPoints(t2) << endl;
cout << so.maxPoints(t3) << endl;
cout << so.maxPoints(t4) << endl;
return 0;
}
Code2: 外部定義規則
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
#include <stdexcept>
using namespace std;
struct Point {
int x;
int y;
Point() : x(0), y(0) {}
Point(int a, int b) : x(a), y(b) {}
};
struct PointValue {
Point point;
int value;
PointValue() : value(0) {}
};
bool my_cmp(const Point &a, const Point b) {
if (a.x != b.x) {
return a.x < b.x;
} else {
return a.y < b.y;
}
}
typedef bool (*comp)(const Point &a, const Point b);
/**
* 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 maxnum = 0;
map<Point, int, comp> imap(my_cmp);
insertToMap(points, imap);
vector<PointValue> newPoints;
clearPoints(newPoints, imap);
maxnum = scanVector(newPoints);
return maxnum;
}
void insertToMap(vector<Point> &points, map<Point, int, comp> &imap) {
for (auto itVar = points.begin(); itVar != points.end(); ++itVar) {
Point pVar = *itVar;
auto it = imap.find(pVar);
if (it != imap.end()) {
// already exist
// int t = it->second;
// it->second = t + 1;
++(it->second);
} else {
// insert to imap
imap.insert( make_pair(pVar, 1) );
}
}
}
void clearPoints(vector<PointValue> &points, map<Point, int, comp> &imap) {
for (auto it = imap.begin(); it != imap.end(); ++it) {
PointValue pv;
pv.point = it->first;
pv.value = it->second;
points.push_back(pv);
}
}
int scanVector(vector<PointValue> &points) {
int maxnum = 0;
if (points.size() == 0) {
return 0;
} else if(points.size() == 1) {
return points[0].value;
} else {
// number of points more than two
int vecSize = points.size();
for (int i = 0; i != vecSize; ++i) {
for(int j = i + 1; j != vecSize; ++j) {
// form a line
int curnum = points[i].value + points[j].value;
if (points[i].point.x == points[j].point.x) {
// vertical
for(int k = j + 1; k != vecSize; ++k) {
if (points[i].point.x == points[k].point.x) {
curnum += points[k].value;
}
}
} else {
// a line with slope
double slpoe = (static_cast<double>(points[i].point.y - points[j].point.y)) / (points[i].point.x - points[j].point.x);
for(int k = j + 1; k != vecSize; ++k) {
double slope1 = (static_cast<double>(points[i].point.y - points[k].point.y)) / (points[i].point.x - points[k].point.x);
if (slpoe == slope1) {
curnum += points[k].value;
// ++curnum; //it is wrong.
}
}
}
if (curnum > maxnum) {
maxnum = curnum;
}
}
}
}
return maxnum;
}
};
int main()
{
vector<Point> t1;
vector<Point> t2(1);
vector<Point> t3(2);
vector<Point> t4(2);
Point t;
t.x = 2; t.y = 1;
t4.push_back(t);
t.x = 4; t.y = 2;
t4.push_back(t);
t.x = 1; t.y = 2;
t4.push_back(t);
Solution so;
cout << so.maxPoints(t1) << endl;
cout << so.maxPoints(t2) << endl;
cout << so.maxPoints(t3) << endl;
cout << so.maxPoints(t4) << endl;
return 0;
}